content:
Beatrixjennifer's Weblog | I realize that I will be born and born again in this samsara, a never ending journey. But as the path has been taught by the Enlightened One, I believe that one day I'll get the end…
Home
About Me and this Blog
Poems
Gallery
Beatrixjennifer's Weblog
I realize that I will be born and born again in this samsara, a never ending journey. But as the path has been taught by the Enlightened One, I believe that one day I'll get the end…
Feeds:
Posts
Comments
Matimu Kali Ini
September 10, 2019 by beatrixjennifer
Bagaimana rasanya mati, lalu kemudian hidup kembali…
Mati bukan dalam arti nafas yang terhenti, atau fisik yang membeku biru.
Tapi mati saat kau meninggalkan semua masa lalu, pikiran-pikiran dan persepsimu tentang hidup yang sebelumnya.
Lalu dalam sekejap engkau hidup kembali, saat kau melihat sinar terang itu dan rasa bahagia yang membuat bibirmu ingin tersenyum, walau sakit masih terasa di sekujur tubuhmu akibat hantaman bertubi-tubi yang mungkin belum seberapa dari siksa neraka.
Ini hidup yang baru, kau lahir kembali walau masih dalam rupa, nama dan wujud yang sama.
Tapi kau tau hidupmu tak akan lagi sama, tak boleh lagi sama.
Semua dosa masa lalu, apakah sudah terhapuskan?
Mungkin belum, tapi setidaknya kesadaranmu seharusnya membuatmu tak lagi melakukan kesalahan yang sama.
Kau adalah jiwa yang baru, jalani hidupmu dengan lebih bermakna.
Matimu kali ini adalah pelajaran dan peringatan untukmu, agar dapat menemukan jalanmu untuk kembali…
Pergunakan kesempatan yang diberikan ini, untuk sungguh-sungguh berlatih, untuk memulai jalan yang telah kau pilih sendiri, agar kau tak lagi tersesat, agar kau semakin mendekatkan diri pada Tuhan dan tak lagi tinggi hati. Karena kau tak lebih dari setitik debu di angkasa dan jagad raya yang luas ini, seperti yang pernah kutunjukkan padamu dulu sekali…
Jangan lengah! Berlatihlah lebih keras lagi, karena waktumu tak lagi banyak!
Yogyakarta, 10 September 2019
~Jen~
15.52
Posted in Contemplation, My life journey | Leave a Comment »
Hidup Baru
June 18, 2019 by beatrixjennifer
Sebenarnya tulisan ini tentang kematian. Topik “kematian” sudah pernah aku tulis juga sebelumnya di tulisan dengan judul Kematian ini. Tapi alih-alih memberi judul “kematian” yang mungkin buat sebagian besar orang menakutkan, maka aku lebih suka menggunakan istilah “Hidup Baru”.
Kenapa sih kok aku ingin menulis topik ini lagi? Karena sejujurnya buatku sekarang, kematian tak lebih dari suatu proses yang memang akan dialami oleh kita semua, makhluk yang masih berada di samsara. Akhir-akhir ini memang ada beberapa peristiwa yang membuat aku kembali merenung dan berpikir tentang kematian.
Entah sejak kapan aku tidak begitu ingat, kematian bukan lagi hal yang menakutkan buatku, tetapi masih menjadi hal yang menyedihkan, karena seperti yang disampaikan oleh Guru Buddha, berpisah dengan yang dicintai adalah sebuah penderitaan. Dan tentu saja penderitaan itu mendatangkan kesedihan.
Dulu aku selalu merasa sedih bila ada orang yang meninggal, ini pula yang membuatku berpikir untuk tidak menjadi seorang dokter, bukan karena aku takut darah ataupun lainnya, tapi lebih kepada aku tidak tahan melihat kematian, karena kupikir aku pasti akan menangis sedih jika menghadapi kematian.
Tetapi perjalanan hidup memberiku begitu banyak pelajaran, kematian demi kematian dari orang-orang disekelilingku dan terdekatku telah membentuk aku yang sekarang. Aku yang sekarang yang tak lagi bersedih saat melihat kematian. Aku yang sekarang yang memandang kematian hanya sebagai suatu bagian dari kenyataan hidup dan proses dalam perjalanan di samsara ini.
Sempat terbersit dalam benakku apakah aku telah berubah menjadi orang yang tidak berperasaan? Tapi setelah merenungkan lebih dalam, tidaklah demikian adanya. Aku pernah menyikapi kematian dengan kemarahan, kesedihan dan ketidakpuasan untuk waktu yang cukup lama. Kematian papi itu mungkin menjadi satu titik balik dalam hidupku dalam proses “mencari kebenaran”. Dan waktu akhirnya memberikanku banyak pelajaran dan jawaban atas tanya dan ketidakpuasanku. Dalam perjalanan waktu, aku bisa memahami pesan yang kuterima, bahwasannya keterikatan dan keakuanlah yang menyebabkan kesedihan itu.
Saat harus sekali lagi mengalami peristiwa kematian orang yang aku cintai, yaitu kematian mami, aku lebih bisa menerimanya dengan berbesar hati. Tentu saja sebagai manusia yang normal yang masih memiliki perasaan dan ego, aku tetap menangis dan merasa kehilangan. Tapi dibalik rasa kesedihan itu aku juga mengerti bahwa kematian itu sesungguhnya tidak pernah memisahkanku dari orang-orang yang kucintai itu. Mereka hanya sudah terlebih dahulu memulai hidup yang baru, dalam wujud dan dimensi yang berbeda, dan suatu saat nanti mungkin aku akan kembali bertemu dengan mereka lagi.
Aku menulis tulisan ini dari mulai menunggu boarding hingga sekarang berada di atas pesawat yang membawaku kembali ke Jakarta. Sambil memandang ke luar jendela, melihat hamparan awan-awan putih diselingi mentari senja, mengingatkanku akan masa kecilku. Waktu kecil aku sempat bertanya, apakah orang yang meninggal itu akan berada di awan? Karena pelajaran yang kuterima, surga itu adanya di atas, dan sejauh kumemandang langit terlihat hamparan awan seputih kapas. Ada satu kali, sambil memandang awan di langit, aku menangis, teringat kakekku yang sudah meninggal saat itu. Saat ini, saat memandang awan, kupikir seperti itu pulalah kematian. Kadangkala mereka yang pergi menjadi awan, lalu turun sebagai hujan, bergabung menjadi ombak di lautan hingga kembali menjadi awan begitu seterusnya. Mereka tidak pernah pergi, mereka selalu ada, hanya bagaimana kita bisa mengenalinya dalam wujud dan rupa yang berbeda.
Yang lahir pasti mati, karenanya usahlah bersedih. Hidup yang satu dan hidup yang baru hanya sebatas pemikiran kita. Yang terpenting bagaimana kita bersiap untuk memulai hidup baru yang bisa datang kapan saja menghampiri kita…
Di atas langit senja Jakarta,
~Jen~
05.49 pm
Posted in Contemplation, My life journey | Leave a Comment »
Hidup Bukan Sekedar Hutang Piutang
June 5, 2019 by beatrixjennifer
Akhirnya aku bisa mengunjungi Bhutan, negara yang tingkat kebahagiaan penduduknya tinggi. Jika melihat kondisi alamnya, memang sangat indah dan asri. Dari tour guide lokal aku mengetahui bahwa pemerintah tetap menjaga agar 60% dari area haruslah ditanami pepohonan. Tidak heran udara di sini masih sangat segar dan bersih.
Hari pertama aku punya kesempatan mengunjungi Buddha Point atau Buddha Dordenma, sebuah patung Buddha yang sangat besar yang pembangunannya sudah diramalkan untuk menjaga perdamaian di Bhutan.
Bangunan patung ini sangat besar, di dalamnya masih terdapat ribuan patung-patung Buddha kecil dan juga terdapat patung Buddha Vayrocana dan Buddha-Buddha lainnya. Di dalam ruangan aku sempat bernamaskara dan bermeditasi sejenak. Setelah selesai aku berkeliling di halaman luar ruangan.
Entah apakah ini hanya perasaanku ataukah memang ada ‘pesan’ yang ingin disampaikan padaku, tetapi saat berjalan keliling itu aku jadi menangis, dan seolah ada yang berbicara padaku, kenapa aku berpikir bahwa tidak ada gunanya lagi aku hidup? Tulisanku sebelum ini memang berisi perasaanku tentang hidup yang aku jalani saat ini, bagaimana aku merasa bahwa sepertinya sudah tidak ada gunanya lagi aku hidup setelah kepergian kedua orangtuaku. Tapi pesan yang aku terima di Buddha Donderma menyuruhku membuka mataku, merasakan dengan hatiku, bahwa masih banyak yang bisa aku lakukan, di luar sana masih banyak hal indah yang bisa aku rasakan.
Aku menangis saat mendapat pesan itu, walau singkat, tetapi menguatkan dan menenangkan. Hidup ini tidak hanya sekedar hutang piutang. Dalam perjalanan kali ini aku bertemu orang-orang baru, merasakan cinta kasih dari mereka, dan sebaliknya juga bisa berbagi kasih dengan mereka. Jika hanya didasarkan pada hutang piutang, mungkin kita hanya jadi berhitung, tapi hidup seharusnya tidak seperti itu. Cinta yang aku miliki, berkah yang ada dalam diriku, seyogyanya kupergunakan dengan baik, agar bisa menuntunku pada jalan pembebasan sejati.
Thimphu, Bhutan, 5 June 2019
~Jen~
05.21 am waktu Bhutan
Posted in Contemplation, My life journey | Leave a Comment »
Standing Alone in The Journey
March 31, 2019 by beatrixjennifer
Tidak terasa satu kuartal telah terlewati di 2019 ini. Waktu benar-benar berjalan dengan cepat. Kesibukan menambah cepatnya perjalanan waktu bagiku. Tanpa terasa pula sebentar lagi setahun sudah sejak kepulanganku dari Taiwan. Banyak yang terjadi dalam kurun waktu satu tahun, tapi entah mengapa yang paling mengusikku adalah soal kematian, kepergian orang-orang yang ada di sekitarku.
Sebelum aku berangkat ke Taiwan di 2017, saat masih bekerja dan suka travelling, seringkali karena terlalu sering membawa barang berat, tanganku jadi terkilir alias keseleo. Dan seperti kebiasaan pada umumnya, jika terkilir pastilah yang dicari tukang urut atau sinshe yang bisa pijat. Dulu aku selalu pergi ke satu sinshe di petak sembilan daerah kota. Usianya tidak terlalu tua mungkin masih sekitar 60an nyaris 70, dan jika dilihat orangnya tampak masih sehat dan segar. Setelah kembali dari Taiwan tahun lalu, kebetulan tanteku ingin pergi pijat ke sinshe tersebut dan ternyata mendapat kabar kalau beliau sudah meninggal.
Kelahiran dan kematian bukanlah hal yang aneh dalam kehidupan ini, terlebih buatku yang tengah belajar mengenai ketidakkekalan. Tetapi tetap saja hal ini mengusik diriku. Dalam kurun waktu setahun, siapa saja bisa pergi meninggalkan kita untuk selamanya. Aku jadi teringat selama setahun aku tinggal di Hualian, Taiwan, aku sudah melihat lebih dari 3 kali peristiwa kematian. Memang orang-orang tersebut tidak aku kenal, tapi entah kenapa aku jadi merasa diperlihatkan bahwa betapa tidak kekalnya hidup ini, diingatkan bahwa kapan saja hal ini bisa terjadi pada diriku.
Hal terakhir yang benar-benar mengingatkanku soal ketidakkekalan ini adalah saat aku bermimpi bahwa seseorang memberitahuku bahwa waktu hidupku hanya tinggal 10 tahun lagi. Sebenarnya ini tidak jelek juga bagiku, hidup terlalu lama tanpa makna sama saja seperti mati. Sejujurnya semenjak kepergian mami aku merasa sepertinya sudah tidak ada gunanya lagi aku hidup. Aku sudah tidak bisa membayar hutang budiku di kehidupan ini. Lalu aku tidak punya suami atau anak yang harus aku urus, sementara bagiku kakak adikku seharusnya sudah bisa mengurus diri mereka sendiri.
Kadangkala aku berpikir sudah waktunya aku pergi. Tugas sudah selesai di kehidupan ini, biar kubayar hutang di kehidupan yang akan datang. Mungkin orang akan bertanya kenapa aku tidak berkeluarga? Sejujurnya sebagian diri ini mungkin pernah menginginkannya, tapi sebagian lainnya juga menolaknya. Kupikir ini tidak lepas dari karmaku di banyak kehidupan yang lalu. Jadi jika sekarang aku ditanya kehidupan mana yang aku pilih, aku pikir pada dasarnya kita semua datang seorang diri, dan akan pergi seorang diri.
Berkeluarga ataupun tidak, kita ini tetap sendiri, menempuh jalan seorang diri. Keluargamu adalah teman dalam perjalanan, dan sesungguhnya tidak terbatas keluargamu saja, setiap orang yang kau temui dalam hidupmu adalah teman seperjalanan. Beberapa mungkin sudah berhenti terlebih dahulu sehingga tidak lagi berjalan bersamamu, beberapa mungkin mengambil jalan yang berbeda denganmu, yang bisa saja satu kali nanti di satu masa yang berbeda bisa bertemu kembali denganmu di satu jalan yang sama.
Aku tidak pernah takut sendiri, aku tidak pernah merasa sendiri, dan kematian bahkan bukan akhir buatku. Aku ingin memulai yang baru, tapi entah mengapa sepertinya ada yang masih harus kulunasi di kehidupan ini, dalam kurun waktu yang relatif singkat ini.
Siapapun itu kamu atau kalian, jika memang aku harus melunasi hutangku di kehidupan ini, datanglah padaku, muncullah di hadapanku, karena aku tidak mau berdiam terlalu lama di sini, karena tugas baru sudah menungguku dan jalan sudah menantiku untuk melangkah maju…
Atambua, 31 Maret 2019
~Jen~
08.00WITA
Posted in Contemplation, My life journey | Leave a Comment »
Turning 39
January 10, 2019 by beatrixjennifer
Yup, today is my birthday, and I’m turning 39. Bukan usia yang muda lagi ya, tapi entah kenapa sih gue selalu ngerasa masih muda aja hahaha… kalau bukan karena mata yang udah mulai harus pakai kacamata ples, dan uban di rambut yang udah mulai lebih cepet tumbuhnya, atau kulit yang udah mulai keluar bercak-bercak putih (nasib orang kulitnya putih) pasti gue akan selalu merasa kalau gue ini baru 17 taon (ich lebay) hahaha…
But that’s true, selama ini gue gak merasa kalau gue ini udah tua, hmmm… terlalu pede mungkin ya? Sebenernya kalau dipikir-pikir bukan terlalu pede sih, tapi lebih kepada gue merasa waktu ini jalannya eh larinya udah kayak orang dikejer anjing gila kali ya, ngebut kagak kira-kira. Perasaan kemaren gue baru aja tiup lilin, masa hari ini kudu tiup lilin lagi? Makanya taon ini gue kagak tiup lilin dah, jiaah alasan hahaha bilang aja kagak ada yang nyiapin kue taon ini wkwkwkw…
Tapi bener, eh bener apa nih, bener kalau waktu itu jalannya eh larinya cepet banget, n bener juga kalau taon ini ultah kagak tiup lilin karena kagak ada yang siapin kue wkwkwk… Yah maklum aja, sekarang gue lagi di negara antah berantah lainnya, di Timor Leste tepatnya, negara baru lagi yang gue injek karena urusan pekerjaan. Hm… dipikir-pikir wish taon lalu jadi kejadian ya. Taon lalu gue ulang tahun di Taiwan, merayakan bareng temen-temen baru, sementara taon sebelumnya gue ultah di Vietnam, dibuatin surprise party sama child fruit (baca: anak buah, wkwkwk). Taon lalu gue sempet bilang, udah dua taon ini ngerayain ultah di negara orang, taon depan gue akan ngerayain di mana lagi? Daaaan.. kejadian donk, taon ini gue ngerayain ultah di negara orang lagi (ya emang negara orang, masa sih negara m*nyet hahaha).
Beda dengan dua taon sebelumnya, taon ini tidak ada perayaan, ucapan selamat pun kayaknya mulai berkurang nih, jiaahhh diitungin hahaha… ya kadang gue pengen tau aja sih siapa-siapa yang masih inget ultah gue, care ama gue, ciee… tapi biar gak ngucapin juga bukan berarti tuh orang gak care sih, emang mungkin kagak tau aje, atau lupa, ya even some of my best friends cannot remember my birthday. Trus cuma gegara dia lupa ultah loe jadi bukan best friend lagi? Hahaha ya gak lah ya, semakin nambah umur gue ceritanya makin wise neh wkwkwk jadi menurut gue tuh, ada orang yang memang gak pay attention to hal-hal begini, jadi ya dimaklumin aja. Even bokap gue aja pernah salah tulis nama gue donk hahaha, it doesn’t mean bokap gue gak care ama gue, tapi emang gue tau aja, nama gue terlalu susah buat bokap gue inget! hahaha…
Nah agak serius dikit neh sekarang, cie serius, eh beneran tadinya gue mo nulis ini maksudnya kontemplasi di hari ultah, tapi entah kenapa ye kok jadinya tulisan chit chat ala gue gini wkwkw tapi asik juga sih, udah lama gak nulis dengan gaya gila gue ini hahaha… back to laptop (ya ampun ketauan banget ye jaman tontonannya hahaha). Oke serius-serius sekarang. Nah jadi gini, kemaren-kemaren ini gue jadi mulai mikir, ich kok gue tiga taon ini ultah di negara beda-beda ya, ini kok jadi seperti loe lahir lagi di tempat-tempat yang beda, ini jadi buat gue mikir mungkin seperti ini juga saat kita terlahir lagi. Kita bisa lahir di tempat dan kondisi yang menyenangkan buat kita, tapi bisa juga lahir di tempat dan kondisi yang kurang menyenangkan. Tapi menyenangkan dan nggak itu kan bagaimana gue sendiri yang ‘mengatur’ dan ‘merasakan’ nya.
Mungkin akan ada orang yang bilang kasihan ya, ulang tahun jauh dari keluarga karena urusan kerja, sendirian lagi. Hm… ya itu sih biar aja orang mo ngomong apa, gue sih happy-happy aja, karena nambah taon ato nggak benernya sih gak beda buat gue. Nambah taon ini benernya cuma pengingat buat gue, pengingat apa? Pengingat kalau umur gue udah berkurang lagi, waktu hidup gue di dunia ini tambah sedikit.
Gue mo cerita dikit nih, ini emang aneh, ini kejadian taon lalu, waktu gue di Hualien, kadang kan gue suka jalan sendiri tuh keluar, olah raga sekalian aja kadang otak gue ini mikir ke sana kemari. Nah ceritanya ada satu kali entah gimana mulanya, gue itu kepikir, sebenernya orang mati tuh lebih baik loe tau kapan waktunya jadi loe bisa prepare, or mendingan dadakan aja langsung aja lu cabut. Kenapa gue mikir gini? Ya gue lagi keinget aja antara bokap n nyokap. Bokap pergi cepet, kata nyokap enak sih gak ngerasain sakit (kek tau aja ye, sapa tau juga saat itu bokap ngerasain sakit hahaha), sementara buat yang ditinggal terutama gue waktu itu, gak terima banget sih. Nah beda waktu nyokap, karena emang waktu itu nyokap sakit, gue tau sih pasti itu sakit banget dan nyokap benernya gak mau tapi ya gimana ya mi, emang itu apa yang sudah seharusnya terjadi, tapi buat gue entah kenapa gue merasa lebih tenang karena saat itu gue merasa gue bisa mempersiapkan segalanya, termasuk say sorry ke nyokap dan mengantar nyokap pergi untuk terakhir kalinya. Nah singat cerita setelah mikirin hal ini, eh entah gimana tuh beberapa hari kemudian gue mimpi donk, dalam mimpi tuh kek ada yang bilang ke gue, jadi waktu hidup gue itu tinggal 10 taon lagi. Nah waktu gue bangun gue cuma mikir gini, hm… 10 taon lagi, jadi gue gak lewat umur 50 taon ya, hm.. bagus jugalah, gue gak pengen idup sampe lama-lama, gue gak pengen mati dalam kondisi muka gue udah keriput, gue pengen mati masih cantik! wkwkwk aiyooo gila juga gue ya…. hahaha… tapi ini beneran loh…
Btw ini hari ultah gue and gue talking-talking about death, ich kalau masih ada nyokap bakal dikemplang gue, pamali masa hari ultah ngomongnya gitu? hahaha ya ya ya gak salah sih, semua orang selalu waktu ultah diselametin semoga Panjang umur, gue tau deh kenapa, karena benernya everybody knows kalau loe ultah itu tandanya umur loe bakal kurang satu ya jadi semoga nanti bisa Panjang umur nyaaa… hahaha…
Okeh, kayaknya udah cukup kegilaan gue hari ini, karena di sini benernya udah lewat hari, maklum 2 jam lebih cepet dari Indo, so gue harus mengakhiri tulisan ini. Dan inti dari semua celotehan gak jelas gue ini adalah, gue cuma mau bilang ke diri gue sendiri:
Happy Birthday Jen, thank you for this 38 years, you hang on and survived. I know it’s not an easy life for you, but you did well so far. Be sincere and accept whatever waiting for you in this journey. I know you can do it! 加油!
Okeh that’s it, dan seperti masih mengikuti tradisi keluarga, hari ini tetap harus makan mie goreng ya, jadi karena darurat dan gak tau apakah bisa keluar makan mie goreng ato nggak, jadi ya terpaksa kita bikin saja. Thanks to Indomie Goreng (ich iklan, hahaha) yang dimasak pakai rice cooker jadi jugalah ya mie ulang taon ala ala wkwkwk….
Dili – Timor Leste, 11 January 2019 00:45 am
~Jen~
(10 January 2019 in Jakarta 10:45 pm)
Posted in Chit chat ala gue, Contemplation, My life journey | Leave a Comment »
Sebuah Refleksi
December 31, 2018 by beatrixjennifer
Satu tahun lagi akan berganti, sepertinya tiap akhir tahun hampir setiap orang akan menuliskan pencapaian dan refleksi apa yang terjadi di tahun ini dan harapan serta resolusi mereka untuk tahun yang akan datang. Dan hampir setiap tahun juga aku melakukan hal yang serupa, hanya sekedar sebagai pengingat untuk diri sendiri.
Sebenarnya tahun baru maupun hari biasa adalah sama saja, yang menjadikannya berbeda karena kita membuat suatu ukuran atas satu periode masa dimana seolah satu rentang waktu telah kita lalui dan kita memberikan penambahan angka di sana. Buatku yang lahir di bulan awal tahun membuat pergantian tahun juga bermakna sebagai usia yang bertambah. Bertambahnya usia bagiku adalah sama dengan berkurangnya umurku untuk hidup di dunia ini.
Aku masih ingat, dulu waktu usiaku masih kepala 2, rasanya waktu berjalan begitu lambat, tapi entah kenapa sekarang ini setelah menginjak kepala 3, waktu berjalan terasa begitu cepat. Aku sendiri kadang masih tidak merasa bahwa aku sudah tua, tapi usia memang tidak bisa bohong, sebagai manusia kita mengalami fase pembentukan, berkembang, kerusakan atau pelapukan, lalu mati. Saat ini di usia yang sudah hampir kepala 4 yang berarti sudah lebih dari setengah usia hidup rata-rata orang Indonesia khususnya, tentunya tubuh ini sudah mulai mengalami fase pelapukan. Rambut yang tadinya bewarna hitam sudah mulai berubah putih, kulit yang tadinya putih mulus sudah mulai timbul bercak-bercak tanda penuaan, dan masih banyak tanda-tanda lainnya yang menandakan bahwa tubuh ini sudah tak lagi sama seperti yang dulu. Memang segala sesuatu yang terkondisi tidaklah kekal, tubuh jasmani ini tentunya juga mengalami perubahan.
Tahun 2018 ini, setelah memutuskan kembali ke Indonesia, aku akhirnya kembali ke dunia kerja. Kembali bekerja berarti kembali ke dunia dimana aku akan menghadapi masalah-masalah dan orang-orang baru dengan beribu satu karakternya. Kadangkala hal ini sangat melelahkanku yang lebih suka sendiri. Buatku, yang melelahkan dari bekerja itu adalah saat harus berinteraksi dengan banyak orang. Tapi aku menyadari, kita hidup di dunia ini tidak sendiri, tidak bisa terlepas dari peranan orang lain. Makanan yang kita makan, pakaian yang kita pakai, semua itu ada jasa orang-orang yang berperan di dalamnya. Hutang piutang tidak bisa dihindari, dan tentulah hutang harus dibayar. Menyadari hal ini, aku hanya berusaha untuk membayar segala apa yang seharusnya aku lunasi.
Banyak hal yang terjadi di 2018 ini, tapi dari semuanya, aku cukup dibuat berpikir keras oleh dua kejadian yang serupa dengan dua orang berbeda, dimana yang satu malah terhitung orang asing bagiku. Tetapi anehnya, kedua orang ini memberikan nasihat yang serupa, nasihat yang seolah mematahkan tekad dan pemikiranku. Sebenarnya aku sangat berterima kasih kepada dua orang ini, karena aku percaya yang mereka sampaikan kepadaku itu adalah dengan maksud dan tujuan yang baik dari lubuk hati mereka. Tapi buatku yang sudah membuat keputusan ini, apa yang mereka sampaikan membuatku jadi berpikir. Ada pepatah bilang, saat kita bertekad untuk melakukan sesuatu, kadangkala ujian itu datang, banyak gangguan dan godaan-godaan yang berusaha menggagalkan tekad kita. Aku jadi berpikir, apakah kedua orang yang bermaksud baik ini juga termasuk godaan untuk menggagalkan apa yang telah aku tekadkan? Karena Siddharta sendiri juga mengalami berbagai gangguan sebelum akhirnya mencapai penerangan sejati.
Sejujurnya aku jadi sedikit bimbang, aku sendiri tidak tahu seberapa besar tekadku ini, apakah aku harus bersikeras, ataukah aku membiarkan segala sesuatu mengalir bagaikan air saja? Aku selalu berdoa agar Tuhan menuntun jalanku pada apa yang seharusnya, tapi mengapa aku menemui hal-hal ini? Apakah ini bagian dari jalan yang harus aku lalui?
Kembali lagi aku teringat akan sebuah nasihat, bahwa aku seharusnya menjalani kehidupan ini dengan tulus. Setelah sekian lama mendapat nasihat ini, aku masih belum dapat memahami ketulusan seperti apa yang seharusnya aku miliki dalam menjalani hidup ini? Kemarin tiba-tiba saja aku terpikir, tulus ini mungkin berarti menerima segala apa yang terjadi padaku tanpa mempertanyakannya, lalu menjalaninya dengan sebagaimana seharusnya, tanpa berkeluh kesah, baik itu hal yang menyenangkan maupun yang tidak menyenangkan, karena biar bagaimanapun yang terjadi padaku adalah memang apa yang seharusnya terjadi menurut karmaku sendiri. Jadi mungkin itulah ketulusan yang harus aku jalani.
Dengan kesimpulan sementara ini, aku telah siap membuka hatiku untuk menyambut tahun yang baru dan segala kejutan yang menantiku. Apapun itu, aku akan dengan ikhlas menerimanya, dan dengan tulus menjalaninya. Baik itu hal yang susah ataupun senang, aku akan menerimanya dengan berbesar hati, menjalaninya sebagaimana seharusnya, karena aku percaya Tuhan tidak akan membiarkanku tersesat, sekalipun aku mungkin salah memilih jalan, tapi mungkin disitu ada pelajaran yang bisa kupetik, ada hutang yang masih harus kubayar. Dan aku selalu percaya, akan selalu ada jalan pulang untukku. Sejauh apapun jalan memutar yang mungkin harus kutempuh, sesulit apapun rintangan yang harus aku hadapi, tapi jalan pulang itu selalu ada untukku. Karena aku datang ke dunia ini, untuk menemukan jalan agar dapat kembali kepadaMu Tuhan.
Jakarta, 31 Desember 2018
~Jen~
05.05 pm
Posted in Contemplation, My life journey | Leave a Comment »
Living in Uncertainty
July 25, 2018 by beatrixjennifer
Hidup ini penuh dengan ketidakpastian. Pepatah bijak mengatakan bahwa yang pasti di dunia ini adalah ketidakpastian itu sendiri. Apa yang akan terjadi beberapa tahun ke depan, apa yang terjadi esok, apa yang akan terjadi satu jam ke depan, bahkan apa yang akan terjadi sedetik kemudian, tidak ada seorangpun yang tahu.
Ketidakpastian ini seringkali menimbulkan kekhawatiran-kekhawatiran dalam diri kita manusia. Kita seringkali memiliki banyak perencanaan untuk masa yang akan datang, rencana-rencana yang pastinya kita harapkan dapat berjalan sesuai yang kita pikirkan. Namun kenyataan seringkali berkata lain. Apa yang sudah direncanakan sebaik mungkinpun seringkali tidak terjadi sesuai apa yang diharapkan. Inilah ketidakpastian.
Lalu bagaimanakah seharusnya kita menyikapi ketidakpastian ini? Bagaimana kita mengatasi kekhawatiran yang timbul karenanya?
Dua bulan ini, setelah kembali ke Indonesia, tentunya yang saya lakukan adalah berusaha secepatnya mendapatkan pekerjaan. Selama ini boleh dibilang saya terhitung mudah untuk mendapatkan pekerjaan. Dan karena hal inilah mungkin saya jadi terlalu percaya diri dan berani mengambil keputusan keluar dari pekerjaan saya setahun yang lalu. Ditambah perhitungan waktu yang sudah saya rencanakan dengan baik, saya sangat yakin sekembalinya ke Indonesia saya akan dapat segera bekerja. Namun kembali lagi, karena hidup adalah ketidakpastian, begitupula hidup yang saya jalani. Siapa yang bisa menjamin apa yang sudah saya rencanakan bisa berjalan mulus. Meskipun ada beberapa panggilan kerja, bahkan yang sudah sampai tahap akhir, toh nyatanya sampai hari ini saya masih pengangguran.
Kenyataan ini membuat saya merenungi akan ketidakpastian hidup. Dalam proses menunggu ini saya menyadari kekhawatiran yang mulai saya rasakan. Kekhawatiran ini jelas sangat mengganggu karena di lain sisi saya menyadari tidak seharusnya kita hidup di dalam kekhawatiran. Kita seharusnya “pasrah” dalam menjalani hidup ini. “Pasrah” saya beri tanda kutip, karena “pasrah” di sini bukan berarti kita hanya berdiam diri ataupun menyerah. “Pasrah” atau saya lebih suka pakai istilah Jawa “nrimo” dan “legowo” adalah kondisi dimana batin tidak dipengaruhi kekhawatiran akan apa yang terjadi di kemudian hari. Ini adalah pengertian yang saya buat sendiri untuk diri saya sendiri. Kondisi ini adalah dimana kita sudah berusaha sepenuh hati, merencanakan sebaik mungkin, tapi tetap hasil akhir atau apa yang akan terjadi kita serahkan pada kuasa “Tuhan” sang Maha segala.
Dalam penantian akan ketidakpastian ini saya merasa “Tuhan” tengah mengajari saya untuk hidup di saat ini, hidup dengan “pasrah” di dalam ketidakpastian. Kehidupan ini bukanlah hitungan matematika dimana satu ditambah satu adalah dua seperti yang sudah disepakati oleh manusia. Hidup ini adalah sebuah misteri yang seringkali memberikan kita manusia begitu banyak kejutan. Yang harus saya lakukan adalah bersiap untuk setiap kejutan yang akan saya terima sambil tetap “hidup di saat ini”. Menghargai setiap detik waktu yang saya lewati dengan sebaik mungkin, dengan melakukan hal-hal yang berguna bagi kehidupan ini.
“Tuhan” selalu punya cara-Nya sendiri untuk menegur, mengajari, dan mencintai kita manusia. Dan saya sangat bersyukur bahwa hingga detik ini saya masih menerima pelajaran-pelajaran itu yang tentunya sangat berguna bagi saya dalam menempuh “perjalanan” ini…
Bangka, 25 July 2018
~Jen~
17.55 WIB
Posted in Contemplation, My life journey | Leave a Comment »
Till We Meet Again…
May 23, 2018 by beatrixjennifer
Waktu satu tahun itu begitu cepat berlalu. Tidak terasa setahun sudah aku meninggalkan Indonesia untuk tinggal di Taiwan. Dan sekarang setahun sudah berlalu, berarti saatnya kembali ke Indonesia.
Mungkin hanya beberapa sahabat terbaikku yang sesungguhnya mengerti apa tujuanku pergi ke Taiwan. Sebagian orang lainnya memiliki persepsi masing-masing termasuk anggapan aku datang ke negara ini untuk mencari jodoh? Ya tidak bisa disalahkan karena memang di masa lalu terdapat banyak perempuan Indonesia yang menikah dengan pria Taiwan.
Tapi tujuanku datang kemari lebih untuk mencari jawaban atas pertanyaan-pertanyaan yang belum terjawab dan untuk menunaikan bakti seorang anak, membalaskan budi baik yang sudah diterima. Selebihnya, aku belajar banyak hal di sini, sebuah pengalaman yang sangat berharga, menemukan apa itu arti kebahagiaan, arti kasih seorang ibu, belajar bahwa yang tampak di luar belum tentu sebenarnya, serta belajar arti melepas dan perpisahan.
Sebenarnya banyak sekali yang ingin kutulis, mungkin nanti satu persatu akan kutuliskan. Saat ini menungu boarding untuk kembali ke tanah air, mencoba menuliskan sedikit perasaan yang kurasakan. Tak terasa air mata berlinang, mungkin orang-orang akan memandangku aneh. Tapi biarlah, inilah aku yang selalu apa adanya. Saat ini aku pulang ke Indonesia, tapi satu hari nanti aku akan kembali lagi ke sini, ke Hualien, tempatku seharusnya berada…
Last sunset in Taiwan @Tamsui
Taipei, May 23rd, 2018
~Jen~
13:45 waktu Taipei
Posted in Contemplation, My life journey | Leave a Comment »
Older Posts »
Hi, it’s nice to see you again!
I'm just an ordinary girl from ordinary family who lived in ordinary world and wish to have ordinary life...

label: ms


content: Deskripsi Produk Merupakan mesin press yang digunakan untuk sablon apparel lebih maksimal karena panas dari head platen yang merata. Ukuran dari mesin heatpress ini adalah 40×50 atau setara dengan ukuran A3+ Untuk keterangan lebih lanjut atau link order silakan kunjungi laman dengan klik tombol di bawah :

warc-identified-content-language: eng,ind

warc-type: conversion

content-type: text/plain

label: id


content:
Belum lama ini saya diminta tolong memperbaiki aplikasi lama dalam PHP 5. Aplikasi ini sudah lama dan masih dipakai sampai development aplikasi baru selesai. Aplikasi ditulis dalam PHP dengan framework Code Igniter dengan database MySQL. Deskripsi masalahnya begini: di aplikasi ini setiap hari ada satu halaman yang semakin lambat sampai suatu hari error, tidak bisa diakses lagi.
Pesan popup itu muncul dari komponen datatables.net di browser. Setelah diselidiki: penyebabnya adalah error di sisi server, tepatnya lagi ternyata out of memory di sisi server.
Allowed memory size of 134217728 bytes exhausted (tried to allocate 7077931 bytes) /var/www/html/application/XXX.php
Aplikasi ini meload data dari database menjadi satu file JSON berisi beberapa belas ribu baris. Dari hasil membaca dokumentasi komponen datatables ini, seharusnya mudah membuat paging dengan pemrosesan di sisi server cukup dengan menambah OFFSET dan LIMIT pada query SQL. Tapi ternyata tidak mudah di aplikasi ini.
Kira-kira aplikasinya begini:
$q = "select puluhan_kolom from table where belasan_filter;";
$data=array()
foreach ($rows as $row){
    //isi loop for ini ratusan baris
    //ada beberapa puluh query berdasarkan nilai $row
    //dalam kondisi tertentu data baru ditambahkan ke $data
}
echo json_encode($data);
Jadi untuk tahu berapa jumlah row-nya perlu menjalankan banyak query, bukan hasil count dari query utama. Andaikan tahu jumlah row-nya pun, tetap akan sulit untuk pergi ke halaman-N karena harus memfilter lagi dari awal. Dari berbagai kondisi di dalam loopnya sepertinya banyak hal ad-hoc ditambahkan, atau mungkin juga designnya salah dari awal.
Lalu setelah saya pikirkan lagi: Jika bisa paging pun, fitur lain harus diubah. Datatables menyediakan fitur filtering dan search built in. Jika kita meload data per page, search dan filter ini harus diimplementasikan ulang dengan kode baru di sisi server.
Jadi apa yang bisa saya lakukan? permintaan tolong ini di hari kerja, jadi saya cuma bisa melakukan ini:
menaikkan memory limit PHP
menambah ukuran cache mysql
menginstall PHP opcode cache (APC)
Beberapa hal lain yang tidak saya lakukan:
menginstall PHP 7, karena distribusi Linuxnya terlalu tua. Ribet jika harus menginstall manual
mengubah kode program karena terlalu rumit
Programnya bisa berjalan lagi walau seringkali butuh beberapa menit mendownload JSON sekitar 5.5 MB. Dengan koneksi di indonesia, jika bisa stabil 100 kilobyte/second maka butuh 55 detik untuk mengirim datanya. Itu di luar waktu query, karena transfer data baru bisa dimulai setelah semua data siap. Dari cerita yang saya dapat: Koneksi 100 kilobyte/second (kira-kira 1 Mbit/s) sebenarnya tidak sulit dicapai tapi ketika sambil sharing screen di meeting Zoom, kecepatannya bisa sangat tidak stabil. Belum lagi jika dua orang mengakses halaman yang sama untuk didiskusikan.
Mungkin ada yang heran: memory limit kan 128 MB dan ukuran JSON 5.5MB itu sebenarnya sangat kecil, kenapa bisa out of memory? Struktur internal PHP (terutama PHP versi sebelum 7) sangat tidak efisien, ukuran memori yang dipakai bisa belasan kali lipat dari tipe data dasar di bahasa lain (pernah saya tuliskan di artikel tahun 2009). File JSON itu hanya bentuk akhir saja, array yang menyimpan data sebelum jadi JSON memakai memori besar dan setiap query juga memakan memori.
Quick Fix
Di akhir pekan, saya ubah kodenya seminimal mungkin agar cukup cepat. Pertama yang terlihat jelas adalah mengkompres data. Saya sudah menguji bahwa data JSON hasil aplikasi jika dikompres ukurannya menjadi kurang dari 700kb. Dari kecepatan download saja: data 700 kb bisa didownload dalam 7 detik jika koneksinya 100 kilobyte/second vs 55 detik data aslinya.
Di PHP, kompresi bisa dilakukan dengan:
    ob_start("ob_gzhandler", 16*1024);
    //outputkan data seperti biasa dengan echo
    @ob_end_flush();
Dengan modifikasi kecil ini hasilnya: data bisa diakses kurang dari 7 detik setelah dihasilkan. Masih ada masalah lain: harus menunggu dulu sampai semua query selesai baru bisa dikompresi. Langkah berikutnya adalah mengoutputkan JSON per elemen array. Jadi loopnya diganti kira-kira menjadi seperti ini:
ob_start("ob_gzhandler", 16*1024);
echo '{"data":[';
$first = false;
foreach (/*row*/) {
        if ($data_ok) {
              if ($first)   $first = false; else echo ",";
              echo json_encode($current_data);
        }
}
echo "]}";
@ob_end_flush();
Dengan ini sambil melakukan query, data sudah bisa mulai dikirim ke browser. Aplikasi juga menjadi lebih cepat karena tidak menyimpan data di memori, dan tidak perlu menghasilkan string ukuran besar dengan JSON.
Dengan dua quickfix tersebut plus yang sudah dilakukan sebelumnya (menambah limit memori, memakai cache APC, dan menaikkan limit cache mysql), aplikasi bisa diakses kurang dari 10 detik. Menurut saya ini masih lambat, seharusnya dengan design yang baik, aplikasinya bisa instan menampilkan halaman pertama, dan setiap halaman berikutnya bisa meminta request baru. Tentunya akan lebih banyak kode yang perlu ditulis baik di sisi client maupun server.
Pelajaran
Sebagai catatan: posting ini bukan kritik terhadap PHP. Dalam bahasa manapun kesalahan seperti ini bisa terjadi. Tapi faktor kerakusan memori PHP dan lambatnya PHP versi lama membuat bugnya lebih cepat muncul.
Jika Anda adalah seorang client yang meminta dibuatkan aplikasi: perhatikan ukuran data. Selain menguji bahwa aplikasi sudah berjalan, ujilah juga aplikasi dengan jumlah data yang besarnya sesuai dengan pemakaian. Misalnya ingin membuat aplikasi untuk sekolah offline, jumlah murid mungkin bisa ratusan, atau ribuan sampai beberapa tahun ke depan. Dalam kasus ini jumlah murid tapi tidak akan sampai level jutaan.
Ini juga cerita secara umum: membuat aplikasi sederhana memang tidak sulit, tapi membuat aplikasi yang scalable akan butuh waktu lebih lama dan/atau kode yang lebih banyak. Cerita ini hanya sekedar scaling dari ratusan data (sangat cepat ketika didemokan) sampai ke belasan ribu data (aplikasi sangat lambat lalu mati), belum sampai ke level jutaan atau ratusan juta data yang butuh perencanaan yang lebih matang dan implementasi yang lebih sulit.
This entry was posted in php, umum on July 1, 2020 by admin.
Mencoba Bahasa Dart dan SDK Flutter
Leave a reply
Posting ini akan membahas pengalaman singkat saya memakai bahasa pemrograman Dart dan Software Development Kit (SDK) Flutter di sebuah proyek kecil. Flutter merupakan SDK pembuatan user interface (UI) yang membuat Dart jadi dikenal untuk UI Development. Ini seperti seperti Rails yang membuat Ruby jadi terkenal untuk web development (Ruby on Rails).
Dart programming language
Saya akan bahas sedikit mengenai sejarah bahasa Dart ini supaya jelas bahwa: bahasa ini bukan bahasa baru, dibuat perusahaan besar (Google), memiliki standard resmi (ECMA), dan sudah memiliki sejarah cukup panjang.
Sejarah Dart
Bahasa pemrograman Dart diumumkan Google sejak 2011 dan dirilis publik tahun 2013. Tadinya bahasa ini dikembangkan untuk web browser untuk menyaingi Java Script. Awalnya ada kabar bahwa Virtual Machine untuk Dart akan dimasukkan Chrome, tapi rencananya berubah: Dart ditranslasikan (transcompile) saja ke JavaScript, jadi tidak ada VM khusus Dart dalam browser.
Bahasa Dart ini sempat distandardkan dalam ECMA standard 408 tahun 2014, tapi tahun 2018 bahasanya diubah dengan rilis 2.0 sehingga tidak sepenuhnya kompatibel lagi dengan versi sebelumnya. Spesifikasi terbaru saat ini bisa dilihat di sini. Tapi JavaScript juga terus berubah, plus masih ada saingan bahasa lain yang ditranslasikan ke JavaScript (misalnya TypeScript, CoffeeScript, dsb) jadi Dart kurang menonjol.
Selain Dart, Google juga memiliki bahasa lain yang lebih populer: Go. Selama beberapa tahun nasib dan tujuan Dart ini menurut saya kurang jelas, sampai ketika tahun 2015 Flutter diumumkan.
Bahasa Dart
Bahasa Dart ini menurut saya cukup normal, tidak memiliki konsep yang sangat aneh. Menurut saya ini bagus karena beralih dari berbagai bahasa ke Dart tidak sulit.: “the Dart language aims to be unsurprising“. Contoh sederhana hello world seperti ini:
main()
{
       print("hello world");
}
Berbagai konstruksi standar bahasa Dart mirip dengan bahaca lain yang C-like. Misalnya:
komentar seperti C/C++: /*block comment*/ dan //line comment
sintaks if adalah: if (x) { /*aksi*/ } else { /*aksi lain*/)
sintaks for loop: for (int i=0; i < 10; i++) {/* aksi */}
sintaks while loop: while(kondisi) { /*aksi*/} atau do { /*aksi*/} while (kondisi)
Sintaks OOP-nya juga tidak terlalu jauh dari bahasa C++/Java/C#. Berbagai konsep dari bahasa modern, misalnya mixin, nullable type, null safety, named parameter, async, dsb juga ada di Dart. Ringkasannya: beralih dari bahasa lain ke Dart ini cukup mudah.
Flutter
Flutter adalah SDK yang untuk membuat aplikasi GUI di Android, iOS, Windows, Linux, Web dan Google Fuschia dari satu kode Dart. Flutter juga memungkinkan kita melakukan “live editing“, jadi begitu kode diubah dan disimpan, user interface juga langsung terupdate. Flutter ini diklaim mampu menampilkan user interface 120fps dengan mudah.
Setelah beberapa tahun sejak diumumkan, akhir tahun 2018, Flutter versi 1.0 dirilis. Tapi ternyata sampai saat ini menurut saya Flutter masih belum matang. Masih banyak breaking changes yang muncul. Ini artinya kode yang Anda tulis sekarang mungkin tidak jalan di versi berikutnya.
Kebetulan ada proyek yang saya kerjakan yang membolehkan saya menggunakan Flutter. Ini sekedar proyek Proof Of Concept, jadi nanti bisa ditulis ulang ke bahasa lain. Salah satu alasan kenapa sebuah perusahaan memilih atau menolak bahasa atau teknologi tertentu adalah: takut tidak ada yang bisa meneruskan.
Aplikasi yang saya buat sederhana, memanfaatkan kamera dan Firebase Machine Learning (Firebase ML). Firebase ML adalah bagian dari platform Firebase untuk memudahkan pemakaian machine learning di aplikasi mobile. Contohnya: kita bisa mendeteksi sebuah wajah, dan mendeteksi apakah sedang tersenyum.
Hal-hal yang sudah bagus
Bahasa Dart cukup menyenangkan dan mudah dipakai. Seperti tujuan designnya, bahasa ini dirancang agar tidak mengejutkan dan menurut saya cukup berhasil. Saya tidak punya keluhan khusus di bahasa Dart-nya sendiri.
Flutter sudah didukung oleh Visual Studio Code dengan baik. Instruksi untuk mulai menggunakan Flutter sangat jelas dan saya bisa membuat Hello World dengan cepat. Untuk target Android, Android Studio juga sudah mendukung Flutter dengan baik. Ada tool command line “flutter doctor” yang bisa membantu mendeteksi beberapa masalah dasar.
Library Dart masih sedikit
Beberapa bahasa dianggap terbaik untuk teknologi tertentu karena ketersediaan librarynya. Contoh: Python dianggap terbaik untuk Machine Learning karena sudah ada banyak library Machine Learning tersedia. Jumlah library Dart/Flutter masih sedikit dibandingkan bahasa lain. Library Dart adalah library yang terpakai untuk Dart dan Flutter, sedangkan library Flutter untuk Flutter saja.
Jika dilihat sekilas, memang sepertinya banyak library Dart/Flutter sudah ada, tapi baru terasa ketika membangun aplikasi tertentu. Kadang librarynya sudah ada, tapi fungsi tertentu tidak tersedia.
Kadang sebuah library hanya berjalan untuk versi OS tertentu saja. Plugin resmi juga sifatnya sebagian masih beta, misalnya WebView dan In App Purchase. Kadang library memiliki bug yang lama belum diperbaiki, misalnya di iOS camera memiliki memory leak sejak 2018.
Perlu dicatat bahwa untuk berbagai aplikasi sederhana, library yang tersedia sudah cukup. Aplikasi yang sekedar memakai form yang tidak terlalu kompleks, mengirim data ke web mudah dibuat dan bisa dibuat lebih cepat dibandingkan memakai teknologi lain.
Flutter Masih berkembang
Sistem plugin flutter untuk Android belum lama ini diupdate (Desember 2019), jadi beberapa plugin versi lama tidak berjalan atau memiliki warning. Untuk yang masih berjalanpun, tidak cepat updatenya ke versi terbaru. Saya juga sempat mendapati masalah dengan contoh dari github yang ternyata masih memakai versi plugin lama dan dicampur dengan plugin lain yang memakai library baru.
Semoga saja tidak ada update penting lagi dari Flutter/Dart, karena jika sering ada update maka semakin banyak plugin yang tidak berjalan. Secara umum ini adalah masalah teknologi baru: masih banyak perubahan yang membuat kode lama menjadi tidak berjalan.
Dart kurang cepat
Dibandingkan C, Dart masih puluhan kali atau ratusan kali lebih lambat lebih lambat. Contohnya jika kita ingin memproses gambar dalam Dart, hasilnya akan butuh beberapa detik. Jadi untuk pemrosesan tingkat rendah, sebaiknya memakai plugin atau kode dalam bahasa C.
Dalam kasus aplikasi kecil saya: stream data dari kamera formatnya adalah YUV, sedangkan image library untuk mengencode JPG/PNG perlu input dalam format RGB. Sudah ada yang memberikan kode ini dalam Dart, tapi memproses jutaan piksel ternyata lambat. Supaya cepat, kita harus memanggil kode dalam C.
Komentar: https://github.com/flutter/flutter/issues/26348#issuecomment-617266911
Ini kasus yang nyata dan penting. Contohnya adalah Issue ini di github yang masih aktif dari awal tahun hingga saat ini: https://github.com/flutter/flutter/issues/26348. Untuk pemrosesan di sisi server yang tidak butuh interaktif, 4 detik mungkin cepat, tapi jika tiap kali mengambil foto kamera berhenti selama 4 detik, maka ini akan membuat pengguna kesal.
Foreign Function Interface (FFI) di Dart masih Beta
Jika sebuah bahasa tidak memiliki library atau fitur untuk melakukan sesuatu, maka biasanya kita perlu memakai library dari bahasa lain. Ada banyak cara untuk melakukan ini, misalnya dengan plugin, tapi cara lain adalah dengan FFI (foreign function interface). Intinya kita ingin menulis dalam bahasa tertentu (biasanya C) lalu dipanggil langsung dengan Dart. FFI ini juga kadang dipakai jika Dart terlalu lambat melakukan hal tertentu.
Masalahnya fitur FFI di Dart masih beta, dan tidak bisa dipakai di Dart rilis stabil terbaru. Dalam kasus github yang saya sebutkan sebelumnya: proses yang lambat (butuh beberapa detik dalam dart) bisa selesai dalam hitungan miliseconds di C. Selain itu masih ada kemungkinan berubah:
As of Dart 2.7, dart:ffi is in beta, and breaking API changes might still happen. If you’re developing a Flutter app, you can get access to dart:ffi by using the Flutter dev channel, as described in the Flutter dart:ffi page.
https://dart.dev/guides/libraries/c-interop
Digabungkan dengan beberapa hal di atas, ini jadi masalah yang cukup serius:
Ingin memakai plugin tertentu: ternyata belum ada atau belum diupdate
Ingin diimplementasikan dalam Dart, tapi ternyata tidak cukup cepat
Ingin memakai kode C: tapi FFI tidak bisa jika tidak memakai versi beta
Library kurang cepat diupdate
Saya berharap library Firebase dari Google untuk Flutter cepat diupdate karena Firebase ini adalah produk Google dan Flutter juga produk Google, tapi ternyata tidak demikian. Flutter ini masih dinomorduakan oleh Google dibandingkan yang lain.
Di awal Juni 2020 Ada update Firebase untuk memisahkan bagian AI offline dari yang online di Firebase, tapi sampai saat ini (akhir Juni) belum juga library flutter di update setelah hampir sebulan.
Penutup
Saya berharap Google lebih memperhatikan Flutter lagi. Untuk sistem operasi Google Fuschia, Google akan perlu bahasa yang cocok untuk development aplikasi GUI. Bahasa Go kurang cocok karena sifatnya yang harus dikompilasi (walau kompilasi cukup cepat), sedangkan Google selalu memliki masalah dengan lisensi Java dengan Oracle (dan Kotlin masih sangat erat dengan Java).
Untuk pengembangan cross platform, masih banyak teknologi cross platform lain yang lebih matang (seperti misalnya React Native atau bahkan Cordova). Tapi Flutter ini menurut saya sangat menarik dan developmentnya cukup fun. Jika perkembangannya lancar, mungkin ini bisa jadi bahasa pilihan untuk pembuatan aplikasi GUI.
This entry was posted in Uncategorized on June 27, 2020 by admin.
Assembler di browser berbasis Keystone dengan WebAssembly
2 Replies
Sebenarnya saat ini saya sedang sibuk dengan banyak hal, tapi karena sedang berduka, saya ingin melakukan sesuatu untuk mengalihkan pikiran. Bapak saya suka membongkar mobil untuk mengalihkan pikiran, sedangkan saya lebih suka memprogram sesuatu yang tidak berhubungan dengan pekerjaan. Hasilnya: hari ini saya mengkompilasi framework Keystone dengan target WebAssembly (Wasm) lalu memberi interface HTML dengan Preact (alternatif React yang ukurannya jauh lebih kecil).
Assembler ini bisa diakses online di https://asm.x32.dev dan sourcenya saya berikan di https://github.com/yohanes/online-assembler . Aplikasinya bisa diakses dengan semua browser modern (Safari, Chrome, Firefix, Edge), termasuk juga mobile browser (sudah ditest di iOS 13 dan Android 10).
WebAssembly (Wasam)
Supaya tidak bingung dengan penjelasan assembler dan webassembly, akan saya jelaskan apa itu WebAssembly (biasa disingkat dengan Wasm). WebAssembly adalah format instruksi biner untuk virtual machine (bisa dibayangkan seperti bytecode Java) . Saat ini target utamanya adalah web browser (saat ini sudah disupport di Firefox, Google Chrome, Safari dan Edge). Di masa depan web assembly ini dihrapkan akan bisa dipakai juga di aplikasi desktop maupun server.
Sekarang ini sudah ada compiler supaya kita bisa mengkompilasi bahasa C, C++, Rust, dsb ke kode WebAssembly. Setelah dikompilasi, kodenya bisa dijalankan di browser. Sayangnya API web browser tidak bisa diakses oleh kode web assembly, jadi diperlukan jembatan berupa kode JavaScript.
Keystone
Keystone merupakan library assembler untuk berbagai arsitektur. Diberikan teks assembly, kita bisa memakai library ini untuk mengubahnya menjadi bahasa mesin. Keystone ini sebenarnya memakai bagian dari libary LLVM, tapi diekstrak bagian assemblernya saja. LLVM sendiri merupakan proyek infrastruktur compiler yang memiliki banyak fitur (parser, optimizer, assembler, linker, debugger, dsb) tapi terlalu kompleks dan terlalu besar jika hanya ingin fitur assemblernya saja.
Untuk keperluan development program dalam assembly, Keystone ini belum terlalu layak pakai karena banyak bugnya dan tidak memiliki fitur macro yang ada di banyak assembler modern. Untuk development, sebaiknya pakai saja assembler dari berbagai compiler yang ada. Keystone ini lebih terpakai untuk riset security, patching program, dan berbagai fungsi kecil lain yang overkill jika memakai assembler lengkap dari sebuah compiler. Contoh pemakaian Keystone adalah untuk menyelesaikan soal CTF semacam yang saya selesaikan dua tahun yang lalu.
Jadi supaya jelas: assembly di WebAssembly tidak berhubungan dengan assembler di library Keystone (saat ini keystone belum mendukung web assembly).
EMSDK
Dengan menggunakan emscripten SDK (emsdk), sekarang kita bisa mengkompilasi banyak library dan program yang ditulis dalam bahasa C/C++ dengan target Web Assembly dengan relatif mudah. Jika program atau library memakai configure, kita bisa menjalankan emconfigure ./configure dan jika memakai cmake, kita bisa menjalankan emcmake cmake. Program emconfigure dan emcmake merupakan wrapper, agar ketika configure/cmake dijalankan, maka compiler dan library yang akan dipakai adalah untuk target WASM.
Tentunya tidak semua program dan library bisa dikompilasi dengan mudah. Contoh kode yang tidak bisa dicompile langsung: kode yang butuh library lain, kode yang butuh akses hardware, kode yang butuh akses layanan sistem operasi tertentu, kode yang memakai kode assembly dalam Intel x86 atau ARM, dan masih banyak lagi kasus khusus lain. Dalam kasus seperti ini, kita perlu melakukan porting manual.
Selain mengkompilasi file C menjadi WASM, emsdk juga menghasilkan file Javascript yang gunanya menjadi jembatan antara Javascript dan WASM. Jembatan ini dua arah: kode C yang memanggil fungsi library standar seperti printf akan memanggil kode JavaScript (misalnya kita arahkan menjadi memanggil console.log), dan kita bisa memanggil kode C dari Javascript.
Optimasi ukuran
Saat ini kode yang dihasilkan dari EMSDK masih belum efisien. Library Keystone ketika dicompile dengan target Web Assembly, hasilnya menjadi file 9.7 megabyte. Saat ini ada proyek lain bernama binaryen yang merupakan infrastruktur compiler untuk WebAssembly. Salah satu toolnya adalah wasm-opt yang dapat digunakan untuk mengoptimasi bytecode WASM. Tool yang lain adalah disassembler Web Assembly (disassembler ini saya pakai untuk menyelesaikan soal CTF).
Setelah dioptimasi, library Keystone yang berukuran 9.7 megabyte berkurang menjadi 5.7 megabyte saja. Ketika didistribusikan, file ini masih akan dikompresi dengan gzip dan hasilnya menjadi 1.5 megabyte. Ukurannya memang tidak kecil, tapi kebanyakan foto dan video ukurannya juga sudah ratusan kilobyte.
User Interface
Bagian berikutnya yang perlu dilakukan adalah membuat user interface yang bagus untuk library yang kita compile tersebut. Untuk program yang memakai Simple DirectMedia Layer (SDL) dan OpenGL, kadang kita bisa langsung menjalankannya karena emsdk sudah menyediakan wrapper untuk API HTML Canvas dan WebGL. Sedangkan untuk aplikasi lain, kita perlu membuat interface HTML dan menggunakan JavaScript untuk memanggil kode C.
Alasan saya memporting Keystone agar bisa memakai assembler keystone terbaru dari browser. Sudah ada yang membuat keystone.js tapi sudah lama tidak diupdate.
Tadinya saya hanya ingin memakai HTML + Javascript murni saja untuk user interfacenya. Tapi setelah saya pertimbangkan lagi, memakai library Javascript akan membuat kodenya jadi lebih terstruktur. Tadinya saya akan memakai React, tapi aplikasi kecil dalam React butuh ratusan kilobyte (terutama karena bagian ReactDOM). Jadi saya memakai Preact yang memakai API yang (hampir) sama dengan React tapi ukurannya hanya 9 kilobyte saja (bahkan hanya 4 kilobyte setelah dikompres).
Development JavaScript Modern biasanya dilakukan dengan menggunakan build system, tapi sebenarnya tidak wajib. Karena program saya ini sangat kecil, saya putuskan untuk tidak memakai build system. Semua kode langsung masuk ke file HTML dan JS. Karena saya memakai WASM, browser harus cukup modern, jadi saya bisa memakai berbagai fitur HTML/JS terbaru tanpa butuh berbagai library polyfill.
Penutup
Salah satu cara belajar teknologi Web Assembly adalah dengan memporting berbagai library dan program ke browser dan membuat atau menyesuaikan user interface agar berjalan di browser. Bahasa C/C++ sudah ada sejak lama, dan sudah banyak hal menarik yang dibuat dalam C, berbagai kode yang sudah ada ini bisa dibawa ke browser dan dieksekusi langsung tanpa butuh server (server hanya sekedar untuk menyimpan file saja, tidak untuk eksekusinya).
Semoga artikel singkat ini berguna untuk memulai eksplorasi Web Assembly, dan semoga assembler onlinenya juga bisa terpakai di masa depan, baik untuk saya sendiri maupun orang lain.
This entry was posted in c, html5, javascript, teknis on May 2, 2020 by admin.
Bahasa Pemrograman BASIC
Leave a reply
Setelah membahas Forth dan juga Lua, kali ini saya akan membahas bahasa BASIC (Beginners’ All-purpose Symbolic Instruction Code). Bahasa BASIC ini merupakan bahasa yang sudah ada lama sekali (sejak 1964), tapi ada beberapa hal yang baru-baru ini terjadi yang membuat saya ingin menuliskan tentang bahasa BASIC:
Smile Basic 4 baru dirilis untuk game console Nintendo Switch
Saya melihat seseorang di kontak Facebook yang sedang memberikan pelatihan bahasa BASIC dengan Just BASIC dan banyak peminatnya
Programmer COBOL kembali dibutuhkan di masa Covid-19
BASIC berulang tahun yang ke 56 tanggal 1 Mei
Tiga hal pertama tersebut menunjukkan bahwa:
Minat terhadap bahasa lama (BASIC dan COBOL) ternyata masih cukup besar
Bahasa-bahasa lama ini masih terpakai (tapi dalam artikel ini saya hanya membahas BASIC)
Setelah membaca mengenai SmileBASIC 4, saya segera membeli softwarenya dari Nintendo Shop. Harga softwarenya 25 USD (masih lebih murah dari kebanyakan game di Nintendo Shop), plus harus membeli slot upload seharga 5 USD jika kita ingin mengupload program kita ke server SmileBASIC.
Setelah mencoba-coba lagi Smile BASIC, ternyata memang bahasa BASIC ini masih bisa membuat saya tersenyum Saya masih bisa membuat program dalam bahasa ini dengan cepat, dan bisa membuat animasi sederhana untuk Joshua dalam waktu sangat sebentar (dalam hitungan menit). Saya juga teringat dulu masa-masa saya belajar sendiri bahasa BASIC. Jadi saya ingin bercerita lebih jauh mengenai bahasa BASIC ini.
Animasi huruf yang dibuat hanya dalam beberapa menit
Di masa kejayaannya, BASIC ada di mana-mana:
Ada novel petualangan yang di dalamnya ada kode bahasa BASIC (pernah saya tulis di sini)
Berbagai majalah memberikan listing program bahasa BASIC
Berbagai buku teks mahasiswa juga diberi kode dalam bahasa BASIC untuk bisa langsung dicoba
Banyak orang menghindari bahasa BASIC karena sifatnya yang tidak terstruktur. Ini memang benar untuk BASIC generasi pertama. Ilmuan komputer Djikstra sering dikutip karena mengkritik BASIC, begini katanya:
“It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration”,
Edsger W. Dijkstra – “How do we tell truths that might hurt” . Selected Writings on Computing: A Personal Perspective
Tapi sebenarnya di tulisan lengkapnya, Djikstra tidak cuma mengkritik BASIC, tapi juga bahasa lain seperti FORTRAN dan COBOL yang sampai saat ini masih dipakai.
Setelah kritiknya itu, sebenarnya bahasa BASIC masih berkembang dan generasi berikutnya sebenarnya sudah cocok menjadi bahasa pemula dan bisa digunakan untuk mengajarkan berbagai konsep pemrograman yang baik.
Beberapa Generasi
Bahasa generasi pertama memakai nomor baris, konsep fungsi dan subrutinnya terbatas, dan sulit membuat struktur data kompleks. Contoh keterbatasan adalah: fungsi hanya sekedar formula, tidak bisa membuat fungsi rekursif. Subrutin memakai nomor baris (tidak memakai nama) dan tidak memiliki variabel lokal. Beberapa implementasi bahkan tidak memiliki DEF untuk membuat fungsi. Contoh versi BASIC ini adalah yang ada pada ROM PC XT, dan ROM berbagai hardware komputer rumah tahun 80an.
Seperti apa sih program BASIC ini? ini adalah program sangat sederhana yang tidak berhenti menampilkan “HELLO WORLD”. Programnya mudah dimengerti: cetak tulisan hello world, dan berikutnya GOTO 10, artinya ulangi lagi baris 10, dst.
10 PRINT "HELLO WORLD"
20 GOTO 10
BASIC sangat populer sehingga pernah dibuat dua standard (ISO/ANSI) tentang bahasa BASIC (yang core dan yang full). Kedua standardnya hanya mencakup generasi pertama yang masih menggunakan nomor baris. Bahasa BASIC juga masuk ke banyak device yang bukan PC, misalnya game console dan juga kalkulator.
Saya program HP 39gs untuk menampilkan hari pasaran dari sebuah tanggal
BASIC generasi kedua (Structured Basic) tidak lagi memakai nomor baris (walau beberapa versi secara opsional membolehkan nomor baris), mendukung fungsi dan subrutin dengan variabel lokal, dan mendukung user defined type (struct/record). Contoh BASIC generasi kedua adalah Microsoft QuickBasic.
Tanpa nomor baris, program hello world bisa mirip Python 2 (Python 3 mewajibkan kurung). Apalagi BASIC ini sifatnya tidak case sensitive, jadi PRINT sama dengan print.
print "hello world"
BASIC generasi ketiga sudah seperti bahasa pemrograman lainnya yang berbasis objek, hanya saja syntax-nya meniru BASIC yang lama. Contoh BASIC generasi ketiga ini adalah Visual Basic .NET. Tapi saat ini minat bahasa BASIC generasi terbaru sudah mulai berkurang, bahkan Microsoft sudah tidak akan menambah lagi fitur di Visual Basic.NET.
Menurut saya sendiri, BASIC generasi kedua ini sudah cukup ideal untuk berbagai aplikasi kecil dan program ukuran kecil yang fun. Jika ingin memprogram berorientasi objek, sekalian saja pakai Java/C#/Python atau bahasa lain.
Sederhana
Kenapa bahasa BASIC sempat populer dibandingkan bahasa lain? menurut saya ini gabungan beberapa hal. Masalah utama adalah Keterbatasan hardware: sulit membuat compiler dengan memori terbatas di hardware awal masa komputer personal (awal 1980an). Jadi alternatifnya adalah: memprogram dalam assembly, atau dalam bahasa lain yang sederhana. BASIC menang dibandingkan bahasa lain (misalnya FORTH yang pernah saya bahas di sini), karena sangat mudah dimengerti walaupun baik BASIC maupun FORTH keduanya merupakan bahasa yang interaktif.
Cassette Basic. Pengguna PC XT dulu akan ingat ini. Memori yang bisa diakses kurang dari 64kb
Kesederhanaan Bahasa BASIC ini bisa dilihat dari jumlah statement dasar yang dimiliki. Versi awal yang dikembangkan pencipta BASIC: John G. Kemeny dan Thomas E. Kurtz (disebut Darmouth BASIC) hanya punya 15 statement (LET, PRINT, END, DATA, READ, GOTO, IF, FOR/NEXT, GOSUB, RETURN, DIM, REM, STOP, DEF). Plus ada beberapa fungsi built in seperti misalnya ABS untuk mendapatkan nilai absolute atau SIN/COS/TAN untuk trigonomoetri.
Dengan kesederhanaan ini, mengimplementasikan interpreter BASIC bisa dilakukan dengan memori kecil. Salah satu kesuksesan awal Microsoft (waktu itu namanya masih Micro Soft, bukan satu kata) adalah produk interpeter BASIC yang ditulis oleh Bill Gates dalam assembly (kodenya sudah dibuka, ada di github). Bahkan di kode assembly yang relatif kecil, Bill Gates bisa menyembunyikan Easter Egg.
Kesederhanaan bahasa BASIC juga bisa digunakan sebagai latihan ketika mengimplementasikan sebuah interpreter. Saya sendiri pernah mengimplementasikan interpreter BASIC dalam JavaScript 10 tahun yang lalu (masih berfungsi ada sampai sekarang).
Instan
Kebanyakan implementasi BASIC, bahkan dari jaman PC XT dulu, eksekusinya hampir instan. Dari mengetik kode hingga berjalan tidak dibutuhkan waktu berdetik-detik atau bermenit-menit. Selain itu hampir semua implementasi BASIC menggabungkan editor dan interpreter, jadi mengetik, menjalankan program, dan bahkan mendebug bisa dilakukan di environment yang sama.
Experience memprogram BASIC ini menurut saya masih sulit ditemui di sistem lain, kecuali jika kita mendownload IDE super lengkap dengan ukuran besar. Bahkan berbagai IDE modern dengan fitur lengkap sering sulit dikonfigurasi.
Meskipun cycle untuk mengedit dan menjalankan program bisa cepat, tapi program yang ditulis dalam BASIC relatif lambat. Untungnya sejak awal sebagian besar implementasi BASIC bisa memanggil kode mesin.
Kode dalam bahasa BASIC umumnya dijalankan dalam sebuah interpreter, tapi sejak puluhan tahun yang lalu sudah ada banyak compiler Bahasa BASIC yang bisa menghasilkan native code. Jadi tidak benar jika bahasa BASIC pasti harus diinterpretasi.
Menengok implementasi BASIC Modern
Saat ini ada banyak implementasi BASIC modern, dan saya sudah mencoba cukup banyak. Saya tidak akan membahas semuanya, dan hanya yang menurut saya menarik saja.
QB64
QB64 ini open source dan meniru user interface QBasic/QuickBasic. QB64 tersedia untuk multi platform. Meskipun meniru QBasic, fitur-fitur baru yang dimiliki sangat banyak, termasuk untuk membuat aplikasi serius atau game 3D dan bahkan aplikasi Android. Sayangnya saya tidak suka implementasinya: kode ditranslasikan ke C, alalu dicompile dengan compiler C. Hasilnya: waktu kompilasinya lama, tidak bisa menjalankan program dengan instan seperti QBasic/QuickBasic. Bahkan saat ini versi terbaru dari github yang saya download gagal menjalankan aplikasi hello world.
Just BASIC
Just BASIC ini hanya tersedia di Windows, gratis tapi tidak open source. Kelebihannya dibandingkan solusi yang lain adalah: bisa digunakan untuk membuat aplikasi Windows yang memakai native control di Windows. Just BASIC memakai pendekatan interpreter, dan eksekusinya instan, ketika mengklik RUN, program akan langsung berjalan.
AppGameKit Classic
AppGameKit Classic adalah implementasi BASIC berbayar untuk membuat game. Saya mengenal AppGameKit ini dari Humble Bundle beberapa tahun lalu dan ternyata sampai saat ini masih terus diupdate. Harga penuh aplikasi AppGameKit relatif mahal, tapi sering bisa dibeli murah dengan berbagai diskon dan bundle dari berbagai situs. AppGameKit dapat dipakai untuk membuat game, baik desktop, web, maupun mobile.
Engine utama AppGameKit ini ditulis dalam C++, dan bisa dipanggil langsung dari C++ jika kita mau, tapi mode untuk menjalankan kode BASIC adalah interpretasi. Bahasa BASIC yang didukung adalah generasi 2, jadi kita bisa membuat tipe data sendiri, tapi tidak bisa memakai OOP.
Beberapa tahun lalu ketika mencoba ini, rasanya cukup fun. Cukup mudah membuat game sederhana. Bahkan ada mode sangat bagus untuk membuat game mobile: mode broadcast. Asalkan device Android kita ada di subnet yang sama, kita cukup menjalankan AppGameKit Player di Android, tekan Broadcast di PC, dan akan muncul gamenya di device Androidnya, instan.
SmileBASIC 4
Saya mendengar berita rilis SmileBASIC di Hacker News, jadi ini relatif baru buat saya. SmileBASIC ini juga tersedia untuk game console Nintendo 3DS. Walaupun sulit sekali memprogram dengan layar kecil 3DS, ternyata aplikasi ini cukup populer sehingga mereka membuat versi Nintendo Switchnya.
Bandingkan jumlah memorinya dengan PC XT
Nintendo Switch bisa dihubungkan ke monitor dengan HDMI dan bisa dihubungkan juga ke keyboard dan mouse USB (dan bahkan juga headset USB). Tanpa keyboard USB, kita bisa memprogram dengan keyboard di layar sentuh, tapi ini kurang efisien. Jadi selama saya mencoba SmileBASIC, saya selalu menggunakan keyboard dan mouse dan layar besar (SmileBASIC mendukung sampai dengan resolusi 1280×720).
AppGameKit mudah diprogram, tapi memiliki kelemahan: kita harus mencari sendiri asset (gambar, musik, efek suara) untuk game atau membeli pack terpisah. Sedangkan SmileBASIC memiliki ratusan sprite built in, puluhan music background built in, dan juga puluhan sound effect. Tersedia juga editor bitmap built in jika gambar yang ada tidak seperti yang kita mau.
Tapi SmileBASIC memiliki kelemahan dari segi fitur bahasa BASIC-nya. Meskipun menggunakan BASIC generasi 2 (tanpa line number), tapi SmileBASIC tidak mendukung user defined type.
Penutup
Bahasa BASIC memang sudah tidak terlalu banyak dipakai dibandingkan masa kejayaannya, tapi belajar bahasa ini cukup menyenangkan. Masih ada orang yang bisa mendapatkan uang dari memprogram BASIC. Beberapa game ditulis dalam bahasa BASIC, demikian juga banyak aplikasi sederhana ditulis dalam BASIC. Beberapa aplikasi dalam berbagai bank masih ditulis dengan Visual Basic 6. Meski demikian, jika Anda pemula dan baru mulai belajar pemrograman sebaiknya belajar bahasa lain saja, seperti Python atau PHP.
Belajar bahasa BASIC bisa dipelajari sekedar untuk iseng. Bahasanya sederhana, tidak butuh banyak waktu untuk belajar, tidak seperti belajar Rust, Haskell atau Scala. Bisa juga belajar BASIC supaya bisa belajar membuat interpreter atau compilernya.
This entry was posted in bahasa, umum on May 1, 2020 by admin.
Multithreading dan Multiprocessing di Python
2 Replies
Python adalah salah satu bahasa yang sangat saya sukai, tapi bukan berarti bahasa ini tidak memiliki kekurangan, di tulisan ini saya ingin menunjukkan kekurangan Python dalam memproses data kompleks dengan Python murni (pemrosesan tidak dilakukan di modul native). Kompleks di sini maksudnya pemrosesannya CPU bound (batasan programnya adalah kemampuan CPU, bukan memori atau I/O).
Kelebihan python jelas sangat banyak: mudah dipakai, librarynya banyak, sintaksnya bersih dan mudah dibaca. Library Python untuk berbagai hal (terutama AI) sudah sangat banyak dan banyak yang ditulis dalam native code (C/C++). Dengan library eksternal yang ditulis dalam bahasa C/C++ (kebanyakan library AI), kita tidak perlu memikirkan apapun dalam hal pemrosesan data besar dan kompleks, karena itu dilakukan di level native code.
Multithreading dan Global Interpreter Lock
Dalam banyak bahasa (misalnya C atau Java): jika saya punya algoritma yang lambat untuk data besar, dan datanya masih masuk memori, saya biasanya bisa menyelesaikannya dengan thread. Saya hanya perlu mempartisi data, membuat banyak thread dan mengolah tiap potongan data di thread yang berbeda. Partisi data di sini biasanya mudah: jika bentuknya array, tinggal dibagi saja per N element.
Di Python, solusi dengan multithreading tidak akan berjalan baik karena adanya Global Interpreter Lock. Atau tepatnya lagi: bisa jalan, tapi tidak lebih cepat dari single thread. Adanya GIL berarti di kebanyakan kasus beberapa thread di Python tidak bisa jalan berbarengan. Threading di Python hanya berguna untuk proses yang menunggu I/O (akses file, akses socket, dsb). Jadi jika kita punya prosessor 32 core sekalipun, Python tidak bisa optimal memakai semua core tersebut dengan module threading.
Kadang-kadang mengganti interpreter dengan pypy sudah cukup menyelesaikan masalah komputasi yang berat. Pypy adalah implementasi interpreter Python yang memakai teknologi JIT (Just In Time Compiler), jadi lebih efisien walaupun tetap satu thread saja. Tapi Pypy ini tidak selalu berhasil:
Pypy tidak 100% kompatibel dengan Python
Ada modul-modul yang tidak bisa dipakai di Pypy
Versi Pypy ketinggalan dibandingkan versi Python resmi
Solusi lain seperti Cython juga bisa dipakai, tapi lebih rumit dari sekedar mengganti interpreter.
Multiprocessing
Python memiliki modul multiprocessing, artinya kita bisa menjalankan sebuah fungsi di subproses baru. Overhead untuk memulai proses baru cukup besar, jadi ada kita bisa juga memakai process Pool supaya lebih optimal. Di titik ketika kita membuat subprocess, isi memori saat ini di proses utama akan di-clone ke memori yang sifatnya copy-on-write (COW). Artinya: selama memori tersebut tidak diubah, maka tidak akan dibuat salinannya, hanya akan dishare (dipakai bersama).
Lalu bagaimana kita bisa memanggil fungsi di proses baru dan mendapatkan hasilnya di proses utama? jawabannya adalah: setiap parameter akan di-serialize dan dikirim ke subproses baru. Hasil kembalian fungsi diserialize oleh subproses dan dikembalikan ke proses utama. Ini cukup untuk menyelesaikan banyak masalah. Tapi pendekatan ini tidak sempurna. Proses serialization dilakukan menggunakan modul pickle. Ini titik yang harus diwaspadai, perhatikan contoh kecil ini di mana kita memproses XML dengan minidom.
from xml.dom import minidom
import pickle

myxml = """<?xml version="1.0"?>
<test>
	<item id="11">
		<name>red thing </name>
		<price>100</price>
	</item>
	<item id="12">
		<name>blue thing</name>
		<price>200</price>
	</item>
</test>
"""

doc = minidom.parseString(myxml)

items = doc.getElementsByTagName("item")

firstitem = items[0]

print(firstitem.toxml())

with open("test.bin", "wb") as f:
    f.write(pickle.dumps(firstitem))
Hasil dari pickle bisa dilihat di file test.bin dan jika dilihat dengan editor akan terlihat bahwa ada ‘blue thing’, padahal tidak ada di firstitem. Modul pickle akan melihat semua atribut yang dimiliki oleh sebuah node dan mempickle semuanya, dalam hal ini: parent-nya juga, dan karena parent memiliki semua child, maka semua child-nya juga ikut.
Jika kita menggunakan modul multiprocessing dan mengirimkan satu node ke subprocess, maka yang niatnya hanya mengirimkan satu node, ternyata mengirimkan seluruh DOM ke subprocess. Secara umum, ketika mengirimkan objek apapun, maka kita mulai harus memikirkan: ketika serialisasi dilakukan, apa saja yang akan dibawa oleh objek tersebut.
Objek yang diserialize ini tidak masuk ke memori COW, tapi Python akan mengalokasikan memori baru. Bayangkan jika kita mengirimkan copy seluruh DOM ke semua subprocess (misalnya ada 10 subprocess), hasilnya: penggunaan memori jadi sangat besar. Jika DOM-nya besar, proses serialisasi dan deserialisasi ini juga sangat lambat.
Dalam kasus tertentu, cara yang lebih efisien adalah: kita letakkan apa yang ingin kita proses di objek global, objek global ini akan di-clone ke proses baru (tidak melalui serialization). Ketika kita memanggil subprocess, kita hanya mengirimkan string atau bilangan yang berupa ID. Subprocess kemudian bisa mengakses variabel global berdasarkan ID tersebut. Cara ini efisien dalam mentransfer data dari proses utama ke subprocess, tapi tidak bisa dilakukan untuk sebaliknya. Ketika mengembalikan hasil proses, kita tetap harus memikirkan objek yang kita kembalikan. Untuk nilai kembalian ini, tidak ada trik yang mudah, kita harus berhati-hati agar serialisasi tidak berjalan liar.
Modul multiprocessing juga memiliki beberapa kelas khusus supaya kita bisa mentransfer data dengan lebih efisien antar proses (Queue, Pipe, Manager), tapi penggunaanna cukup rumit dan tidak intuitif, dan rawan salah. Ini juga tidak menyelesaikan masalah serialisasi data kompleks.
Mungkin sebagian orang akan bilang: ah kan gampang, cukup kita lihat setiap kelas yang kita miliki dan cek satu persatu membernya supaya jelas apa yang diserialisasi. Ada beberapa masalah:
Kode kadang ditulis anggota team lain, dan tidak jelas tipe data sebuah variabel member, lebih sulit lagi jika ada list atau dictionary yang tipe datanya tidak jelas
Kadang kita memakai library orang lain (contoh kecil: XML, Graph), yang tidak mudah untuk dimodifikasi. Andaikan bisa dimodifikasi: kita harus memaintain library itu jika ada versi baru
Untuk masalah pertama: Python saat ini memiliki type hint, kita bisa memberikan hint apa tipe sebuah variabel/member. Tipe data tidak akan dicek oleh interpreter python, tapi IDE yang kita pakai bisa membantu mengecek tipe data. Untuk masalah kedua: ini lebih sulit, kita bisa menulis serializer/pickler khusus untuk object tertentu (bisa dibaca di dokumentasi Python), atau menggunakan setstate__ dan __getstate untuk memproses secara khusus member variable tertentu.
Solusi Third Party
Dulu orang menyarankan: pakai saja Jython (implementasi Python dalam Java) atau IronPython (implementasi Python dalam .NET), keduanya tidak memakai Global Interpreter Lock, jadi thread bisa berjalan cepat. Tapi masalah dengan solusi dari pihak lain adalah: maintenance. Sekarang ini baik Jython maupun IronPython tidak dimaintain lagi. Belum lagi dukungan modul yang kurang lengkap.
Saat ini ada beberapa pendekatan lain untuk memudahkan masalah multithread/multiprocess, misalnya Ray, tapi ini masih kurang populer dan kode kita harus diubah untuk mengikuti model komputasi Ray, library ini pun punya masalahnya sendiri. Tentunya saya tetap khawatir dengan library apa saja dari 3rd party bahwa proyek semacam ini tidak bertahan lama.
Data Ukuran Sedang
Masalah yang saya contohkan di atas itu adalah kasus yang sudah saya temui beberapa kali. Jika dari awal diketahui bahwa data akan sangat besar, saya akan memecah data menjadi banyak bagian, lalu membuat proses khusus yang bisa memproses data yang sudah dipecah, atau bahkan menggunakan sistem terdistribusi. Jika data sangat kecil, saya juga tidak akan menggunakan threading sama sekali, cukup satu proses.
Perlu dicatat bahwa jika kita terlalu buru-buru berusaha memakai sistem terdistribusi untuk data yang masih muat di memori, performancenya justru tidak bagus (belum lagi biaya ekstra yang dikeluarkan untuk banyak server). Artikel tahun 2014 ini merupakan contoh yang bagus bahwa kadang command line tools bisa 235 kali lebih cepat dari Hadoop. Ini kasus yang sangat ekstrem, tapi pelajaran yang bisa dipetik adalah: kalau datanya kurang besar, overhead memakai Hadoop atau sistem lain kadang sangat besar.
Contoh yang biasa saya temui adalah: ada program yang hanya memproses sebuah file, biasanya ukurannya puluhan megabyte, tapi kemudian filenya bertumbuh jadi beberapa gigabyte, nilai ini besar (beberapa puluh kali lebih besar dari input biasanya) tapi masih jauh di bawah memori yang tersedia (misalnya server dengan memori 16-256 GB). Program yang tadinya butuh beberapa detik menjadi beberapa menit atau bahkan puluhan menit, sedangkan ketika diubah menjadi multiprocess, tiba-tiba pemakaian memori Python menjadi beberapa puluh gigabyte (karena masalah serialization) dan malah lebih lambat lagi. Memperbaiki skrip seperti ini bisa butuh waktu yang cukup lama.
Secara umum saya tidak suka dengan pendekatan multiprocessing ini: saya memakai bahasa yang managemen memorinya otomatis (contoh: java, C#, Python, Javascript) karena ingin memori diatur otomatis oleh sistem. Kalau memang ingin mengatur memori manual sendiri, lebih baik saya memakai C/C++ sekalian.
Penutup
Python tetap merupakan salah satu bahasa yang saya sukai dan saya tetap akan memakainya untuk berbagai hal. Posting ini hanya untuk menunjukkan bahwa Python juga memiliki keterbatasan. Dengan memahami batasan ini, kita bisa mempertimbangkan:menggunakan pendekatan lain dalam memproses data dengan Python atau memakai bahasa lain yang lebih cocok untuk masalah tersebut.
Perlu dicatat juga bahwa tiap bahasa bisa berubah, baik sintaksnya maupun implementasinya. Contohnya: NodeJS baru punya Worker Thread di Node JS 10 sebagai fitur experimental dan harus diaktifkan dengan flag khusus. Baru pada Node JS 12 yang baru dirilis April tahun 2019 API Worker Thread dianggap stabil dan layak dipakai produksi. Jadi mungkin saja suatu saat masalah multithread ini akan berubah di Python.
This entry was posted in bahasa, python on November 26, 2019 by admin.
Mengenal Bahasa Pemrograman Lua
Leave a reply
Di kesempatan kali ini saya akan memperkenalkan bahasa Lua. Bahasa ini sebenarnya sudah ada cukup lama (sejak 1993), tapi kurang terkenal secara umum. Lua lebih sering dijadikan bahasa scripting untuk aplikasi dan sering kali nama Lua tidak disebut sama sekali. Lua artinya “Bulan” (moon) dalam bahasa portugis. Lua diciptakan oleh Roberto Ierusalimschy, Luiz Henrique de Figueiredo, dan Waldemar Celes, anggota dari Computer Graphics Technology Group (Tecgraf) di Pontifical Catholic University of Rio de Janeiro, di Brazil.
Lua bisa dipakai untuk membuat program/aplikasi seperti bahasa lain, tapi kelebihan bahasa ini adalah dari awal dirancang untuk diembed dalam sebuah aplikasi lain (terutama dalam bahasa sejenis C). Di-embed ini artinya bisa bisa dipakai untuk sistem plugin atau bisa dipakai untuk mengontrol bagian business/game/app logic sementara bagian yang butuh performance tinggi memakai C atau bahasa lain. Lua juga bisa jadi file konfigurasi yang sangat fleksibel.
Lua dipakai di banyak software misalnya Adobe Lightroom, Nmap, Wireshark, dan lighttpd. Seperti saya sebutkan di awal, sering kali berbagai aplikasi menyebutkan bahasa Lua ini hanya sekilas, dan fitur aplikasinya yang lebih ditekankan dengan nama lain, misalnya dokumentasi Nmap menyebutkan tentang Nmap Scripting Engine (NSE) tapi Lua hanya disebut sekilas di tengah. Lua juga banyak dipakai di berbagai game (misalnya World Of Warcraft, Angry Birds) dan game engine. Interpreter Lua ukurannya sangat kecil sehingga bisa dipakai untuk embedded system/IOT (misalnya NodeMCU dan eLua).
Bahasa Lua
Bahasa Lua menurut saya relatif sederhana, tapi juga sangat fleksibel. Sintaksnya tidak aneh, sedikit mirip BASIC atau pascal. Contohnya seperti ini:
print "hello, berapa umur kamu?"
umur = io.read("*n")
if umur >= 17 then
   print("Halo kakak")
else
   print("Halo adik")
end
Bagi sebagian orang mungkin ini agak aneh mengingat bahasa sekarang sudah tidak lagi memakai kata-kata (“then”, “end”) tapi lebih memakai simbol ({} di C/C++/Java/.NET, indentasi di Python), tapi untuk yang dulu memakai Pascal dan BASIC ini terasa cukup wajar. Sebagian besar syntax Lua mirip dengan bahasa lain, tapi ada beberapa hal yang agak aneh. Di Lua, operator kurang dari, lebih besar, sama dengan, semuanya sama dengan bahasa lain (<, >, =) tapi untuk tidak sama dengan, syntax yang dipakai adalah ~=. Syntax untuk komentar juga agak kurang standar, memakai “–” untuk satu baris, dan memakai –[[ untuk komentar multi baris –]].
Secara umum bahasa Lua cukup mudah dibaca bahkan oleh pemula, tidak seperti bahasa Forth (yang saya bahas sebelumnya) atau bahasa fungsional seperti Scala.
Tipe primitif yang didukung Lua adalah: string, number, dan integer. Struktur data utama di Lua adalah table. Secara umum: tabel memetakan sesuatu ke sesuatu yang lain (seperti Map/Dictionary di bahasa lain). Hampir semua hal di Lua diimplementasikan dengan table. Sebuah array di Lua juga adalah tabel yang memetakan indeks dengan sebuah nilai, dengan nilai index awal default adalah 1. Masalah index ini agak mengganggu bagi saya, karena di bahasa lain biasanya array berbasis 0. Sebuah tabel bisa berisi tabel lain untuk merepresentasikan array multi dimensi.
Sebuah struktur (struct) juga bisa direpresentasikan dalam bentuk tabel (memetakan nama field sebagai string ke nilainya). Di Lua, sebuah fungsi juga bisa masuk ke dalam tabel. Contohnya kita bisa saja membuat tabel yang berisi berbagai operasi matriks yang berisi pemetaan nama operasi, misalnya “multiply” dengan implementasi fungsi perkalian matriks.
Lua juga memiliki konsep metatable, yang bisa digunakan untuk mendefinisikan operasi terhadap sebuah variabel. Dengan setmetatable(variabel, sebuahtabel), kita bisa mendefinisikan berbagai operator dan fungsi yang berlaku untuk variabel tersebut. Jadi jika kita ingin membuat sebuah variabel menjadi sebuah tipe matriks, kita bisa membuatnya dengan setmetatable(variabel1, tabel_operasi_matriks).
Lua tidak memiliki konsep OOP tapi dengan menggunakan berbagai trik table, metatable dan fleksibilitas function di Lua, kita bisa mengimplementasikan Object Oriented Programming. Saya sendiri kurang menyukai ini, kalau saya ingin memprogram dengan paradigma OO, saya akan memilih bahasa lain.
Fitur Lua lain yang menarik adalah coroutine, generalisasi dari subrutin, tapi fitur ini jarang saya pakai. Sebenarnya fitur ini powerful, tapi ketika melakukan embeding Lua ke bahasa lain (terutama C), fitur ini cukup merepotkan karena tidak mudah dipetakan ke C.
Embeding Lua ke bahasa C
Seperti sudah saya sebutkan di atas, fitur Lua adalah sangat cocok untuk diembed ke sebuah aplikasi. Sebenarnya bahasa lain seperti Python dan Ruby juga bisa diembed ke bahasa lain (misalnya C), tapi ada banyak kelebihan Lua:
Ukurannya sangat kecil, ratusan kilobyte. Python butuh minimal beberapa megabyte (disk space dan memori)
Mendukung multi thread (satu thread menjalankan instance Lua terpisah). Untuk embedding multi thread di Python sangat sulit, dan Python memiliki Global Interpreter Lock
Interfacing sangat mudah, baik coding manual atau dengan bantuan SWIG
Implementasi utama Lua adalah dalam bahasa C, walau ada juga Lua untuk Java. Kebanyakan bahasa memiliki build system yang kompleks dan butuh banyak library tambahan. Dalam kasus Lua: kita cuma perlu copy paste semua file .c (kecuali lua.c) ke project kita dan itu sudah cukup. Sebagai catatan: selain implementasi utama Lua, ada juga LuaJIT yang sangat cepat namun memiliki banyak batasan terutama di sistem 64 bit.
Setelah memasukkan semua file C dalam project kita, di bagian program yang butuh Lua, kita perlu menginclude beberapa file:

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

Lalu kita bisa menginstansiasi interpreter Lua. Jika diperlukan, kita bisa membuat banyak instance (misalnya satu di setiap thread). Setelah itu biasanya kita ingin agar library standar Lua diaktifkan, jadi kita memakai luaL_openlibs.
lua_State *L = luaL_newstate();
luaL_openlibs(L);
Biasanya skrip Lua akan diletakkan di luar program, supaya bisa diubah dengan mudah tanpa rekompilasi. Untuk meload dari file, kita bisa memakai luaL_loadfile atau luaL_loadstring jika ingin memakai string. Di banyak Game, file lua dienkrip di file (agar tidak mudah dimodifikasi), lalu didekrip dimemor, dan diload menggunakan luaL_loadstring.

int err = luaL_loadfile(L, "myscript.lua");
if (err) {
       fprintf(stderr, "Failed loading file: %s\n", lua_tostring(L, -1));
       exit(1);
}
Dalam passing parameter ke Lua dan dari Lua, kita menggunakan konsep stack. Kita bisa memasukkan nilai ke stack dengan lua_pushstring/lua_pushnumber/lua_pushinteger, dan bisa mengambil nilai di stack dengan lua_tointeger, lua_tostring, lua_tonumber dan beberapa fungsi lain. Jadi ketika memanggil fungsi di Lua: kita melakukan push value ke stack, dan untuk mengambil nilai dari lua kita akses hasilnya di stack juga.
Kita bisa mencari fungsi yang diimplementasikan di Lua dengan lua_getglobal(L, "namafungsi"), ini akan mempush reference fungsi ke stack. Setelah itu kita bisa mempush nilai parameter untuk fungsi, memanggil fungsinya, dan mendapatkan hasilnya di stack.

lua_getglobal(L, "myfunction");
lua_pushinteger(L, 1); //param 1
lua_pushinteger(L, 2);  //param 2
int err = lua_pcall(L,
    2 /*number of arguments*/,
    1 /*number of result*/,
    0 /*indeks ke error handler, jika 0 maka error akan dipush ke stack*/);
Membuat fungsi di C yang bisa dipanggil oleh Lua juga sangat mudah. Misalnya kita ingin membuat fungsi max yang menerima 2 double dari Lua dan mengembalikan angka terbesar, maka kita cukup membuat ini:

int max_for_lua(lua_State *L)
{
  double num1 = lua_tointeger(L, 1); //param 1 dari Lua
  double num2 = lua_tointeger(L, 2); //param 2 dari Lua

  double max = num1>num2?num1:num2; //logika utama

  lua_pushnumber(L, max); //push ke stack Lua
  return 1; //hanya ada satu nilai kembalian
}
Tentunya keberadaan fungsi ini perlu diberitahukan ke Lua agar bisa diakses oleh skrip Lua. Nama fungsi di C dan Lua bisa berbeda, contohnya fungsi max_for_lua di atas bisa didaftarkan menjadi “my_max” seperti ini:

lua_pushcfunction(lua_state, max_for_lua);
lua_setglobal(lua_state, "my_max");
Penutup
Sering kali saya menemukan di mana saya butuh eksperimen cepat dan tidak ingin sering mengcompile ulang kode program saya. Contoh penggunaan yang baru-baru ini saya lakukan adalah ketika eksplorasi fitur tertentu di iOS. Jika saya mengandalkan objective C atau Swift saja, tiap kali saya mengubah kode (biasanya hanya logic tertentu), akan butuh beberapa detik sampai beberapa puluh detik sampai bisa menjalankan ulang aplikasinya. Walau hanya menekan tombol “run” di XCode yang terjadi di latar belakang adalah: kodenya harus dicompile, dilink, ditandangani secara digital, dicopy ke device, lalu dijalankan. Dengan memindahkan logic ke Lua, saya hanya perlu me-mount direktori dokumen aplikasi dengan ifuse, mengedit file Lua, lalu merestart aplikasinya.
Menambahkan sebuah scripting ke language ke aplikasi memang butuh waktu tapi di sisi lain juga sangat fleksibel karena skrip bisa dimodifikasi dengan cepat dan tidak seperti kode C, tidak perlu dikompilasi ulang. Jika Anda sudah beberapa kali menambahkan fitur scripting ke sebuah aplikasi, menambahkan ke aplikasi berikutnya tidak butuh waktu lama. Untuk aplikasi kompleks kita bisa memakai Simplified Wrapper and Interface Generator (SWIG) untuk mempercepat membuat interface dari C/C++ ke Lua.
Semoga tulisan singkat ini cukup untuk memperkenalkan bahasa Lua dan mungkin juga membuat Anda tertarik untuk menambahkan Lua ke aplikasi yang Anda buat.
This entry was posted in bahasa, lua, teknis on August 3, 2019 by admin.
Dari keyboard ditekan sampai muncul karakter di layar (bagian 3)
Leave a reply
Di bagian sebelumnya sudah dibahas mengenai bagaimana layout text harus dilakukan. Setelah semuanya selesai, maka teks bisa ditampilkan ke layar. Di level aplikasi biasanya kita hanya perlu memanggil semua fungsi dasar untuk menampilkan teks. Di sisi library dan sistem operasi, masih ada langkah ekstra yang harus dilakukan. Teks perlu digambar ke sebuah buffer dan buffer perlu ditampilkan di sebuah permukaan gambar. Driver grafik akan menampilkan buffer tersebut ke layar.
Untuk aplikasi desktop, proses menampilkan teks ini di sisi programmer semudah memanggil fungsi print (mode teks) atau mengeset property tertenty. Jika kita memprogram microcontroller atau embedded system, akan lebih terasa proses berat yang harus dilakukan ketika menampilkan sesuatu. Contoh paling sederhana adalah 7 segment display.
Programmer perlu menyala matikan tiap garis dalam 7 segment display untuk menampilkan angka tertentu.
Display saat ini biasanya menggunakan akses per piksel. Mungkin yang paling sederhana adalah 8×8 dot matrix. Di sini kita perlu mengontrol tiap titik untuk menampilkan huruf/angka/bentuk yang kita mau.
Semakin canggih hardware, biasanya pekerjaan programmer high level akan semakin mudah. Contohnya adalah display LCD jenis seperti ini:
Jpeg
Demikian seri singkat kali ini. Saya akan berusaha membuat seri baru yang membahas dari segi yang lebih low level lagi.
This entry was posted in hardware, teknis, umum on April 11, 2019 by admin.
Dari keyboard ditekan sampai muncul karakter di layar (bagian 2)
Leave a reply
Meneruskan dari tulisan sebelumnya, sekarang kita ke bagian aplikasi. Pertama aplikasi perlu menerima “event” dari Desktop/Window environment. Event ini bermacam-macam, misalnya permintaan untuk meminimize Window, event gerakan mouse, dan event tombol keyboard ditekan.
Setelah tombol ditekan, maka aplikasi akan melakukan update pada struktur datanya. Sebagai pengingat, contoh aplikasi yang saya berikan ada Word Processor. Ini bergantung dari mode saat ini (apakah mode insert atau overwrite, apakah dokumen sifatnya read only dsb). Struktur data yang digunakan pun bisa sangat beragam, tergantung dari fitur yang dimiliki aplikasi.
Dalam sebuah word processor, berbagai algoritma perlu dijalankan sebelum tampilan diupdate di layar. Beberapa algoritmanya misalnya: hyphenation (pemotongan kata), pemeriksa ejaan (dalam kasus tertentu biasanya nanti kata tersebut perlu digaris bawahi merah), perhitungan jumlah kata.
Ketika data di memori perlu ditampilkan di layar, maka ada banyak langkah lagi yang harus dilakukan. Mulai dari pencarian font, layout setiap karakter, dsb.
Sebuah font perlu diload sebelum bisa ditampilkan di layar. Font jaman dulu merupakan font bitmap biasa, tapi font sekarang biasanya merupakan true type font yang memiliki banyak informasi untuk tiap glyph dalam font tersebut. Jika kita memiliki satu kata yang ingin ditampilkan, maka ada kemungkinan:
Satu huruf dipetakan ke satu glyph
Satu huruf dipetakan ke lebih dari satu glyph, contohnya jika ada diacritic
Dua huruf atau lebih dipetakan menjadi satu glyph (contohnya jika ada ligature)
Jika dokumen terdiri dari lebih dari satu bahasa maka hal ini menjadi lebih kompleks lagi, ada bahasa yang ditulis dari kiri ke kanan dan dari kanan ke kiri. Berbagai hal ini biasanya dilakukan dalam tahap yang dinamakan “text-shaping”. Setelah semuanya siap, maka teks bisa ditampilkan di layar.
Bagian berikutnya akan membahas bagaimana teks ditampilkan di layar.
This entry was posted in teknis, umum on December 30, 2018 by admin.
Dari keyboard ditekan sampai muncul karakter di layar (bagian 1)
Leave a reply
Seri tulisan ini akan mencoba menjelaskan apa yang terjadi dari sejak kita menekan tombol di keyboard sampai muncul huruf di layar. Untuk mempersingkat, saya akan mengambil beberapa asumsi:
Keyboard ditekan di sebuah aplikasi yang terbuka (jadi sudah selesai booting)
Sistem operasi yang dipakai modern (bukan DOS, tapi Windows/Linux/OS X)
Aplikasi yang akan saya contohkan adalah sebuah word processor (supaya sederhana, rencananya saya akan menulis dari mengetik di address bar sampai muncul web page)
Keyboard
Ketika tombol di tekan di keyboard, sebuah saklar akan aktif. Ada banyak jenis saklar ini (bisa dibaca di wikipedia) tapi intinya sebuah sirkuit akan tertutup ketika tombol ditekan. Karena jumlah tombol ada banyak, maka digunakan sirkuit matriks pada keyboard untuk mengurangi jumlah koneksi.
Keyboard tidak tahu apa yang tertulis di atas sebuah tombol. Tombol pertama di keyboard QWERTY adalah huruf ‘Q’, tapi di keyboard AZERTY menjadi ‘A’. Keyboard hanya akan mengirimkan kode sebuah tombol, nanti urusan setting di sistem operasi yang akan menginterpretasikan tombol itu menjadi suatu huruf tertentu.
Sebuah keyboard memiliki prosessor, sebuah chip khusus atau microcontroller yang akan melakukan scanning pada matrix keyboard. Di keyboard lama (PS/2), jika ada tombol ditekan maka akan mengirimkan sebuah interrupt ke PC. Di keyboard USB, PC akan melakukan polling (biasanya 150Hz), artinya dalam 1 detik komputer akan bertanya 150 kali pada keyboard: apakah ada tombol yang sedang ditekan?
Jika ingin mengenal bagian ini lebih dalam, kita bisa membeli Arduino, dan keypad matrix sederhana seperti dalam gambar berikut ini.
Atau seperti ini yang lebih jelas terlihat koneksinya
Kita juga bisa membeli keycap satuan untuk keyboard mekanis, dan bahkan merangkai sendiri circuit boardnya. Microcontroller yang digunakan dalam proyek DIY seperti ini biasanya Atmega32u yang mudah diprogram.
Jika ingin membuat keyboard custom sendiri juga tidak sulit. Misalnya kita bisa membuat keyboard yang mengetik alamat email jika satu tombol ditekan. Atau mungkin kita tidak ingin memakai tombol tapi pedal.
Sistem Operasi
Input dari keyboard akan diterima oleh sistem operasi. Untuk keyboard USB, driver HID (human interface device) akan menerima data dari keyboard. Di titik ini, setiap sistem operasi memiliki jalurnya sendiri dalam menangani keyboard.
Di Linux/Unix, jika kita memakai XWindow, maka X Server akan membaca input dari /dev/input/* dan meneruskan eventnya ke berbagai Window yang muncul. Di Windows driver akan mengirimkan message ke System Message Queue.
Shell/Desktop
Ketika sebuah tombol ditekan, maka ada Desktop manager yang akan mengatur: saat ini aplikasi yang aktif yang mana? mana yang menerima input keyboard? kadang ada lebih dari satu aplikasi yang menerima input keyboard, ada aplikasi yang mendaftarkan diri sebagai shortcut handler (misalnya ketika tombol print screen ditekan, maka isi layar akan disimpan ke DropBox).
Berikutnya …
Di sebuah aplikasi akan ada event handler yang menangani input dari keyboard. Ini akan saya bahas di bagian berikutnya.
This entry was posted in teknis, umum on November 30, 2018 by admin.
Membaca Source Code
Leave a reply
Ada beberapa pertanyaan yang ditujukan ke saya yang jawabannya mudah jika sang penanya bisa membaca source code. Sayangnya skill membaca source code ini sering kali tidak dimiliki, padahal sangat diperlukan oleh programmer dan juga para reverse engineer.
Saat ini mungkin sekitar 90% pertanyaan programming bisa dicari jawabannya dengan Google, dan biasanya jawabannya akan ditemukan di situs stack overflow, di blog seseorang, dan kadang di beberapa situs yang memang membahas topik khusus yang dicari.
Tentunya jawaban-jawaban tersebut bisa ditemukan kalau Anda bisa berbahasa Inggris. Minimal tahu beberapa kata kunci untuk mencari, dan sisanya adalah kemampuan membaca teks berbahasa Inggris. Segala macam pertanyaan sederhana sudah ada yang menanyakan, misalnya “how to split string in <java/c/javascript/..>”. Sering kali jawabannya disertai source code fungsinya, misalnya untuk pertanyaan cara split string di C yang tidak ada di library standar.
Selain berbagai jawaban di stack overflow, dan artikel di berbagai situs, ada juga berbagai buku dan dokumen yang bisa dibaca untuk mencari jawaban. Tapi ada satu sumber yang paling akurat untuk pertanyaan programming: source code. Kadang informasi dari dokumentasi bisa salah atau belum diupdate, tapi informasi dari source code tidak akan salah.
Saat ini sebagian besar software yang dipakai sudah open source. Berbagai sistem operasi sourcenya terbuka (Linux, FreeBSD, OS X, dan masih banyak lagi), compiler dan interpreter (gcc, llvm, go, php, python, dsb), editor text biasa ( emacs, notepad++, vi, dsb) atau bahkan IDE (IntelliJ, Eclipse, Visual Studio Code, dsb). Berbagai game, editor audio, konverter video, dsb semuanya ada versi open sourcenya. Berbagai library sudah ada untuk melakukan hampir apa saja, dari mulai decoding format file sampai mengenali wajah dan suara.
Tidak semua software memiliki dokumentasi yang lengkap. Contohnya: meskipun jutaan orang memakai OS X, dan kernel OS X ini open source, sedikit sekali dokumentasi dan buku mengenai internal kernel OS X. Jika untuk software yang sangat populer saja dokumentasinya tidak banyak, tentunya masih ada ratusan ribu software lain yang dokumentasinya lebih sedikit lagi.
Dokumentasi sebuah fungsi di sebuah bahasa juga sering kali tidak menyebut detail implementasi, yang kadang penting dari sisi security, misalnya dokumentasi mt_rand dan mt_srand di PHP tidak menyebutkan bagaimana proses seeding dilakukan jika tidak dinyatakan secara eksplisit. Tentunya ini bisa ditanyakan ke stack overflow, dan dalam kasus ini ada yang menjawab untuk versi PHP yang spesifik (dan dia mendapatkan jawabannya dari source code).
Dari sisi security, kita bisa menemukan kelemahan dari membaca source code. Dalam kasus mt_rand, sudah pernah ada dua bug ditemukan (tahun 2008 dan 2011). Bug di software yang menggunakan PHP sehubungan dengan penggunaan mt_rand juga masih sering ditemukan (misalnya salah satu yang relatif baru di Oktober 2017).
Membaca source code tanpa alasan yang kuat memang jarang dilakukan orang. Tapi ketika terpaksa, sebaiknya kita mampu membaca kode orang lain. Sering kali kita tidak perlu membaca dalam, biasanya hanya sekedar permukaan saja atau langsung spesifik ke bagian tertentu, tergantung kebutuhan. Membaca source code besar tidak bisa seperti membaca novel dari halaman pertama ke terakhir. Membaca source code besar harus memakai berbagai pendekatan.
Pendekatan pertama adalah skimming, sekedar melihat berbagai file yang ada, lalu membuka file tersebut. Cek apakah ada komentarnya. Hal paling penting adalah mengetahui apakah file tersebut dipakai atau tidak. Sebagian file ternyata tidak dipakai, sebagian ternyata hanya dikompilasi jika fitur tertentu diaktifkan (sedangkan defaultnya fitur tersebut tidak aktif).
Hal penting lain yang bisa didapat dari sekedar skimming adalah: library apa yang dipakai oleh program ini atau program eksternal apa yang dipanggil oleh program ini? Kadang ternyata source code yang kita temukan tidak sesuai harapan karena ternyata hanya membungkus library atau command line lain.
Pendekatan berikutnya adalah menjalankan program tersebut. Ini bisa langsung dilakukan jika program tidak perlu dicompile dan tidak butuh server tertentu (contoh: sebagian program butuh server database). Jika program perlu dicompile, langkah ini juga memberikan banyak informasi. Kita jadi tahu file apa saja yang ternyata dicompile, jadi tahu library apa yang dilink, dsb.
Jika sudah bisa menjalankan program, akan lebih baik lagi jika bisa mendebug program. Beberapa program memang sangat sulit didebug, contohnya kernel Linux di Android butuh setup yang tidak mudah, plus perlu belajar memakai GDB. Tapi jika debugger bisa dipakai, maka ini akan memudahkan pemahaman program. Jika debugger tidak bisa dipakai, maka cara lain adalah menggunakan “print” debugging.
Sebagai catatan: berbagai langkah bisa dilakukan bersamaan. Mengkompilasi source code kadang butuh waktu lama (berjam-jam) atau mendownload requirement (berbagai library yang dibutuhkan) butuh waktu berjam-jam. Sementara kompilasi dilakkan, kode bisa dibaca. Kalau kodenya terlalu besar untuk didownload (contoh: ukuran source code Qt ukurannya ratusan megabyte) bisa source code versi online yang dibaca (misalnya di github).
Sebuah IDE akan sangat membantu untuk membaca program: mencari tahu di mana sebuah fungsi didefinisikan, dari mana saja fungsi dipanggil bisa dialakukan dengan mudah. Untuk memahami program sangat besar (misalnya kernel Linux) biasanya sebuah IDE kurang bisa dipakai (terlalu lambat). Sebagai alternatif, program cross reference (misalnya LXR) bisa dipakai.
Jika program memiliki unit test, maka test ini juga bisa menjadi cara untuk memahami fungsi tertentu. Unit test hanya memanggil satu modul program saja untuk menguji kebenarannya, jadi kita bisa mengerti satu bagian kecil program tersebut.
Perhatikan juga bahwa kadang aplikasi yang populer sudah sangat kompleks karena memiliki banyak optimasi. Contohnya jika hanya ingin memahami membuat web server, maka bisa diawali dengan membaca source code sederhana, lalu kemudian bisa diteruskan dengan membaca yang lebih rumit. Jika Anda belum paham dasar web server, dan langsung membaca source code Apache, maka kemungkinan besar Anda akan bingung.
Beberapa hal butuh dasar teori yang baik, contohnya: memahami source code library kompresi butuh dasar teori mengenai kompresi. Memahami implementasi encoder/decoder MP3 juga akan mustahil jika tidak punya dasar teori mengenai pendengaran manusia (dan banyak konsep matematika).
Hal yang paling penting ketika membaca source code adalah: motivasi. Tanpa motivasi tertentu, membaca source code memang sangat membosankan. Motivasi membaca source code ini bisa banyak, dan tergantung masing-masing orang. Beberapa contoh hal yang pernah memotivasi saya:
Ada konfigurasi yang tidak jalan, dan saya tidak mengerti kenapa, sedangkan dokumentasinya kurang jelas
Saya ingin memahami bug tertentu (misalnya ini)
Saya perlu tahu implementasi algoritma tertentu
Saya perlu mencari bug untuk tujuan pentesting. Misalnya ada software lama tapi tidak menemukan eksploitnya di web

warc-identified-content-language: ind,eng

label: ceb

label: en