Category: Uncategorized

Singapore

I’ve been to Singapore a few times, and each visit makes me feel more familiar with the city.

Singapore is so different from where I live, everything’s super organized and they take rules seriously. I spent almost two weeks there once, but maybe not long enough to decide if it is something boring or not. I thought there was something beautiful about all that orderliness.


Working From H

I live in a village and see a mountain range view with an unfinished high-speed rail almost every day. My neighbors are often quiet, and there is less noisy highway car volume. It’s a good place for WFH.

On the contrary, if I get bored, the first place that comes to my mind is a city. It’s a place full of fast-walking people who mind their own business, with a line of buildings that compete to be seen as the grandest, and a lot of people inside who seem to be working hard.

Sometimes it’s nice to work in a city designed for people to work, but it all depends.


Nostalgia with Pascal

Pascal is my first programming language. I started learning it in my first year of senior high school. I remember writing a code to print “Hello World” in my first class, and then my teacher gave me a list of reserved words in Pascal to remember. Since then, I have learned a lot about programming languages.

Back then, I don’t know what I can be by learning computer programming. There were no software companies in the province where I lived, and the capital city was so far away. So, I didn’t know if a profession called “software engineer” existed.

I kept playing around with programming because it was cool, and I also participated in the National Olympiad of Informatics in my country. So, I always practiced math and programming every Tuesday and Thursday afternoon at my school. But my dream was to graduate from college and become a teacher, which I later regretted in college when I joined a teacher training program at a high school in Bandung.

I created a lot of small programs and games with Pascal, but sadly I didn’t know about GitHub back then, so none of those codes got backed up. This week, when I was feeling nostalgic for Pascal, I decided to create a simple game with it. And here it is: Katla, a Wordle clone in Indonesian, written in Pascal.

https://github.com/afief/katla-pascal


Trapped in ES5

One of the platforms that I develop and maintain for my current employer is the LG SmartTV App, and the oldest TV version we support is the LG TV with webOS 3.5. Most of the TVs with this OS were released in 2017, but the OS itself is based on Chromium 38, which was released in August 2014, around three years earlier.

Everything is fine since we transpile our code into ES5 using Babel. However, when I needed to update the legacy scripts inside index.html that were not transpiled, something surprised me.

I added a default parameter to a JavaScript function, but it made the app unable to run on that webOS version. I realized that a default parameter is part of ES6 and was only available since Chromium 49. Luckily, we managed to fix that before it was released to production.

It’s funny; I thought that feature had already been available for a long time, but apparently, the OS couldn’t handle it. As a programmer who has been coding JavaScript before the ES6 existence, I had already forgotten the excitement when welcoming the ES6 features, so I thought it was released a decade ago. Thanks to caniuse.com, we can always check the browser/engine support.


Ngelanturin Minat Baca

Kalian suka kangen enggak si, dengan memori ketika kalian enggak punya agenda lain selain baca komik Doraemon yang baru dibeli dari Gramedia di siang harinya. Dibaca setiap halaman dengan pelan, dinikmati setiap gambarnya, sambil berimajinasi apa yang sedang terjadi dengan Nobita di Jepang sana.

Trus kalian nemu satu halaman yang cukup relate. Seperti ketika mereka membahas tentang Ensiklopedi, dan kalian punya ensiklopedi sendiri di rumah.

Trus kalian berhenti sejenak dari baca komik, untuk coba liat ada apa aja di ensiklopedi. Buka halaman secara acak dan menemukan kalimat yang belum pernah kalian tau, beserta penjelasannya.


Dulu gue punya banyak komik, dari Doraemon sampe Dragon Ball, komplit. Komik – komik itu yang mungkin membuat gue waktu kecil jadi rajin baca. Mulai dari baca ensiklopedi hingga biografi Presiden Suharto.

Tapi entah kenapa gue ngerasa minat baca gue sekarang berkurang. Gue lebih suka nonton tutorial berupa video ketimbang baca tutorial berformat teks secara runut. Kalaupun gue mencari suatu informasi dan ketemu artiket yang berkaitan, gue cenderung untuk hanya mencari informasi yang gue butuhkan di artiket tersebut, tanpa baca secara hati-hati dari kalimat pertama. Dan kadang itu membuat gue kehilangan konteks dari artikel yang gue temukan.

Gue ngerasa gue selalu dikejar waktu. Sehingga informasi yang gue butuhkan harus didapat secepat mungkin, tanpa mempelajari hal lain yang mungkin berkaitan dengan informasi tersebut. Padahal kalo ngomongin waktu, gue cukup rajin buka twitter atau scroll instagram, dan itu justru lebih membuang waktu.

Sampe sekarang gue belum menemukan teknik yang manjur buat mengurangi kebiasaan itu. Yang bisa gue lakukan sekarang adalah cek screen time di iphone untuk lihat persentase aplikasi yang gue buka. Antara Social Networking, Productivity, atau Entertainment. Selama ini Social Networking masih merajai, namun berprogress meskipun lambat berkurang. Semoga gak kecanduan sosmed lagi.


Generator Bilangan Prima

Ini hanyalah contoh tambahan dari tulisan yang gue tulis sebelumnya disini https://afief.net/iterables-iterator-generator.

function * primeNumbers (count = 10) {
  const numbers = []
  let current = 2
  const isPrime = (num) => !numbers.find(v => Number.isInteger(num / v))
  while (true) {
    if (count <= 0) break
    if (isPrime(current)) {
      numbers.push(current)
      yield current
      count--
    }
    current++
  }
}

Untuk membuat 15 bilangan prima, cukup dengan

[...primeNumbers(15)]
// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]


Iterables, iterator, dan generator function

Ribuan programmer mungkin tidak menyadari bahwa Array di Javascript bukanlah Array yang seutuhnya tanpa Symbol.iterator. Misal, kita punya array

const fibo = [1, 1, 2, 3, 5, 8, 13, 21]

Lalu, dengan for...of..., kita akan lihat value dari variable tersebut satu per satu.

for (let v of fibo) console.log(v)
// 1 1 2 3 5 8 13 21

Nilai dari variable tersebut ditampilkan sesuai ekspektasi. Hal itu bisa terjadi karena Array yang kita kenal merupakan iterables. Iterables memiliki fungsi yang membuat nilai-nilai di data tersebut dapat dilihat secara berurutan. Bisa dengan menggunakan statemen for...of..., bisa juga dengan spread operator (...).

Salah satu ciri dari iterables adalah memuat property [Symbol.iterator] yang merupakan function. Secara default property tersebut ada di variable yang memuat Array, String, Set, Map, atau TypedArray. Nah, apa yang terjadi kalau kita ubah Symbol.iterator di itarables menjadi bukan function?

fibo[Symbol.iterator] = ''

for (let v of fibo) console.log(v)
// TypeError: fibo is not iterable

Statement diatas akan melempar error karena for...of... membutuhkan dan memanggil iterable property—Symbol.iterator—agar mendapatkan iterator yang berfungsi untuk mengatur nilai-nilai yang akan diberikan ke variable v.

Membuat Non-Iterable Object menjadi Iterable

Untuk membuat object biasa menjadi iterable, kita perlu menambahkan Symbol.iterator ke dalam object tersebut. Symbol.iterator harus berupa function yang mengembalikan iterator. Iterator harus memuat function next() yang akan dipanggil beberapa kali dan mengatur nilai yang akan dikeluarkan setiap pemanggilan function tersebut.

Misal, kita mempunyai object berupa data member yang dikelompokkan berdasarkan ranking.

const members = {
  beginner: [
    { name: 'John', retired: true },
    { name: 'Lucas'},
    { name: 'Doni'}
  ],
  advance: [
    { name: 'Toni' },
    { name: 'Jessica', retired: true },
    { name: 'Angelia' }
  ]
}

Lalu kita perlu membuat object tersebut menjadi iterables agar kita dapat menggunakan Spread Operator untuk membuat array yang berisi semua member yang belum retired. Maka, kita bisa menambahkan Symbol.iterator ke dalam object tersebut sebagai berikut

members[Symbol.iterator] = function () {
  const usersByRanks = Object.values(this)
  let rankIndex = 0
  let userIndex = 0
  return {
    next() {
      if (userIndex >= usersByRanks[rankIndex].length) {
        rankIndex++
        userIndex = 0
      }
      if (rankIndex >= usersByRanks.length) {
        return { done: true }
      }
      if (usersByRanks[rankIndex][userIndex].retired) {
        userIndex++
        return this.next()
      }
      return { done: false, value: usersByRanks[rankIndex][userIndex++]}
    }
  }
}

Kini, setiap kali object members tersebut digunakan di for...of... loop atau di spread operator, variabel rankIndex dan userIndex di set menjadi 0 dan berfungsi sebagai “cursor” yang mengatur nilai mana yang akan dikeluarkan di setiap pemanggilan next().

console.log([...members])
// [ { name: 'Lucas' },   { name: 'Doni' },   { name: 'Toni' },   { name: 'Angelia' } ]

Tanpa menggunakan spread operator, kita juga bisa mengambil satu per satu nilai dari variable members diatas dengan memanggil function next() melalui iteratornya.

const iterator = members[Symbol.iterator]()
console.log(iterator.next())
// { done: false, value: { name: 'Lucas' } }
console.log(iterator.next())
// { done: false, value: { name: 'Doni' } }
console.log(iterator.next())
// { done: false, value: { name: 'Toni' } }

Generator Function

Generator function adalah function yang menghasilkan iterator. Ciri dari function ini adalah adanya tambahan asterik * pada setiap deklarasinya. Di generator function, kita juga menggunakan yield untuk mengembalikan nilai yang dibutuhkan pada setiap iterasi. yield hanya perlu mengembalikan nilai tanpa perlu menambahkan property done.

Berikut contoh pernggunaan generator function menggantikan function iterator manual pada object member

members[Symbol.iterator] = function * () {
  const usersByRanks = Object.values(this)
  let rankIndex = 0
  let userIndex = 0
  while (true) {
    if (userIndex >= usersByRanks[rankIndex].length) {
      rankIndex++
      userIndex = 0
    }
    if (rankIndex >= usersByRanks.length) {
      break
    }
    if (usersByRanks[rankIndex][userIndex].retired) {
      userIndex++
      continue
    }
    yield usersByRanks[rankIndex][userIndex++] // user
  }
}

Loop while akan terus berputar sampai kondisi rankIndex >= usersByRanks.length terpenuhi. Dan apabila kondisi usersByRanks[rankIndex][userIndex].retired tidak terpenuhi, maka keyword yield akan digunakan untuk mengeluarkan nilai user selanjutnya.

Selain membuat object menjadi iterables, generator function juga dapat digunakan secara mandiri untuk membuat sebuah iterator. Berikut adalah generator function yang menghasilkan iterator untuk bilangan fibonacci

function * fibo (maxCount = 1000) {
  let previous = 1
  let initial = 0
  while (maxCount-- > 0) {
    const nextValue = initial + previous
    yield nextValue
    previous = initial
  initial = nextValue
  }
}
console.log([...fibo(10)])
// [ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]

Generator function diatas menerima satu argumen sebagai jumlah maksimal bilangan fibonacci yang akan dihasilkan.


Blog usang yang “hampir” terlupakan

Kemarin pagi, saat iseng cari nama lengkap sendiri di google, yang muncul di halaman pertama hanyalah beberapa sosial media dan tautan – tautan di website pemerintah dan kampus. Blog dan landing page dengan nama sendiri malah hanya ada di halaman kedua.

Tulisan terakhir di blog ini pun hampir dua tahun lalu. Sungguh sebagai seorang suami yang bertemu istrinya pertama kali di komunitas blogger kampus, ini adalah sebuah wanprestasi.

Blog yang—setelah gue coba kembali login—memunculkan banyak notifikasi update pun kembali gue ulik. Dan gue pun menemukan Block Editor.

Editor wordpress yang masih baru buat gue ini terlihat lebih bersih dari editor sebelumnya. Tak perlu enter dua kali untuk membuat paragraf baru. Cukup enter sekali akan terlihat perbedaan antar paragraf. Kita juga bisa ganti style setiap block di menu yang muncul di block tersebut.

Setiap block juga gampang untuk digeser ke atas maupun ke bawah. Ini berguna banget kalo kita mau sisipin gambar, lalu pindahin gambar itu ke atas / bawah paragraf tertentu.

Kira – kira, apalagi ya fitur di WordPress baru yang belum gue tau dan bikin semangat nulis lagi? ?


Await loop over an object

I always rely on bluebird each / all to loop over an array. Until someday I meet the case where I need to use await loop over an object. Surprisingly, after trying on chrome inspector, for loop on object is very doable :

const delayed = (v) => {
  return new Promise((res) => {
    setTimeout(() => {
      res(v)
    }, 1000)
  })
}
const test = async () => {
  const k = { a: 'Happy', b: 'New', c: 'Year!' }
  for (let i in k) {
    let text = await delayed(k[i])
    console.log(text)
  }
  console.log('DONE!')
}
test ()

Above codes will print a text on variable k with delay every 1 second.


Bekraf Developer Conference

Bekraf Developer Conference

Minggu – Senin kemarin dateng ke salah satu acara dari Bekraf di Aston Simatupang Jakarta Selatan, Bekraf Developer Conference. Ini acara puncak dari rangkaian acara Bekraf Developer Day yang diadakan di beberapa kota sebelumnya.

Selayaknya sebuah konferensi, goal dari acaranya ini adalah merumuskan tantangan para developer dan solusi yang bisa disampaikan ke para pemangku kebijakan. Dari konferensi yang diadakan hingga jam 10 malam tsb, dirumuskan banyak tantangan dan solusi yang dapat kalian lihat disini.