1 poin oleh GN⁺ 1 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • zig fmt dapat digunakan sebagai formatter yang bisa dikendalikan yang mencerminkan bentuk sintaks yang sudah ada di file, sehingga kode yang sama bisa ditata dalam beberapa layout berbeda
  • Pada pemanggilan fungsi, ada atau tidaknya trailing comma mengubah hasil; tanpa koma kode digabung menjadi satu baris, sedangkan dengan koma argumen ditempatkan per baris
  • Alur kerja nyatanya adalah menentukan dulu tata letak kode yang diinginkan, menambahkan beberapa koma, lalu menekan pintasan format agar zig fmt menangani sisanya
  • Pada array, selain trailing comma, posisi line break pertama juga ikut tercermin, sehingga jika line break pertama ada setelah item ketiga maka penyelarasan dilakukan per 3 item
  • Jika konkatenasi array ++ digunakan dengan cermat, jumlah item per baris bisa dibuat berbeda-beda, dan saat mengirim pasangan --key dan value ke subprocess, array argumen tetap dan array pasangan opsi bisa digabung untuk dirapikan

Cara mengendalikan zig fmt

  • zig fmt dapat digunakan sebagai formatter yang bisa dikendalikan karena ia melihat bentuk sintaks yang sudah ada di file saat ini dan bisa menata sintaks yang sama dengan beberapa cara berbeda
  • Pada pemanggilan fungsi, ada atau tidaknya trailing comma mengubah layout
    f(1, 2,
          3);
    
    // -> zig fmt ->
    
        f(1, 2, 3);
    
    f(1, 2,
          3,);
    
    // -> zig fmt ->
    
        f(
            1,
            2,
            3,
        );
    
  • Alur penggunaan nyatanya adalah menentukan dulu tata letak kode yang diinginkan, menambahkan beberapa ,, lalu menekan pintasan format agar zig fmt menangani sisanya
  • Alih-alih membiarkan formatter menebak layout, pendekatan yang lebih cocok bisa jadi adalah membiarkan pengguna meninggalkan pilihan inti itu secara langsung
  • Kesimpulannya, 90% formatting yang baik bergantung pada baris kosong di antara blok logis dan pemilihan variabel perantara yang tepat, jadi lebih baik memanfaatkan pilihan-pilihan itu daripada menghilangkannya

Layout perataan kolom pada array

  • Pada array, bukan hanya trailing comma yang menentukan agar elemen disusun satu per baris; posisi line break pertama juga diperhitungkan oleh zig fmt
    .{ 1, 2, 3,
          4, 5, 6, 7, 8, 9, 10, 11,  };
    
  • Jika line break pertama ada setelah item ketiga, hasilnya juga akan disejajarkan per 3 item
    .{
            1,  2,  3,
            4,  5,  6,
            7,  8,  9,
            10, 11,
        };
    
  • Jika konkatenasi array ++ digunakan dengan cermat, jumlah item per baris bisa dibuat berbeda-beda
  • Saat mengirim pasangan --key dan value ke subprocess, array argumen tetap dan array pasangan opsi bisa digabung lalu dirapikan seperti berikut
    try run(&(.{ "aws", "s3", "sync", path, url } ++ .{
        "--include",            "*.html",
        "--include",            "*.xml",
        "--metadata-directive", "REPLACE",
        "--cache-control",      "max-age=0",
    }));
    

1 komentar

 
GN⁺ 1 jam lalu
Opini di Lobste.rs
  • Saya ingat gofmt juga punya perilaku pengarah format yang mirip, dan saya lebih suka formatter seperti itu dibanding rustfmt
    Meski begitu, menurut saya bentuk otomatisasi format apa pun tetap lebih baik daripada tidak ada formatter sama sekali

    • Kalimat “apa pun lebih baik daripada tidak ada formatter” agak sulit dibiarkan begitu saja
      Auto-formatter memaksakan kebiasaan standar, mengangkat orang yang tidak pandai menata format, tapi juga menurunkan kualitas orang yang justru pandai melakukannya
      Saya akan memakainya saat kolaborasi jika sulit mempercayai apa yang diinginkan orang lain atau aturan format pribadi mereka, tapi saat bekerja sendiri saya sama sekali tidak akan memakainya
      Saya punya selera sendiri dan formatter juga punya seleranya sendiri, dan keduanya berbeda secara tak terdamaikan
      Meski begitu, isi yang ditunjukkan tulisan ini sendiri cukup mengesankan
      Kalimat itu mengingatkan saya pada dialog mak comblang Yente di Fiddler on the Roof: “suami yang buruk pun—Tuhan jauhkanlah—masih lebih baik daripada tidak punya suami sama sekali!”
    • Kalau tidak salah, formatter Elm juga bekerja mirip seperti ini, dan rasanya jauh lebih baik dibanding formatter yang sama sekali tidak mempertimbangkan format awal
    • Saya memakai clang-format di beberapa proyek C++, dan itu mengerikan
      Stabilitas antaversinya terlalu rendah, jadi upgrade clang-format berujung pada commit format yang menyentuh setiap baris kode
      Saya benar-benar tidak yakin itu lebih baik daripada tidak punya formatter sama sekali
    • Dulu saya lama berpikir “formatter apa pun lebih baik daripada tidak ada”, tapi belakangan saya berubah pikiran total
      Auto-formatter terutama menyelesaikan masalah manusia dengan menghilangkan perdebatan remeh soal gaya di pull request
      Tapi sekarang saat beralih ke pengembangan berbasis agen, masalah itu makin kurang penting
      Saat ini mesin mengerjakan sebagian besar pekerjaan di beberapa proyek, dan dalam kondisi seperti itu rasanya justru lebih baik tidak menjalankan formatter
  • Saat menyusun argumen command line di Python, saya suka cara splat tuple ke dalam list, jadi contoh terakhir di tulisan itu mungkin akan saya tulis seperti ini

    [  
      "aws",  
      "s3",  
      "sync",  
      path,  
      url,  
            *("--include", "*.html"),  
      *("--include", "*.xml"),  
      *("--metadata-directive", "REPLACE"),  
      *("--cache-control", "max-age=0"),  
    ]  
    
  • Terakhir kali saya lihat, zig fmt tidak punya cara untuk mengatur agar memakai batas 80 kolom alih-alih 100 kolom; apakah masih begitu?
    Kalau bekerja beberapa jam sehari, mata saya jadi tidak terlalu lelah kalau ukuran font terminal dibesarkan, dan perbedaan antara 80 kolom dan 100 kolom menentukan apakah dua split vim dan nerd tree bisa diletakkan berdampingan atau tidak

    • zig fmt tidak punya batas kolom
  • Sebagai orang yang pernah memperkenalkan rigid formatter ke tim yang sebelumnya sama sekali tidak punya formatter, kadang saya merindukan kemampuan untuk tetap bisa memengaruhi format secara manual
    Dalam hal itu, fleksibilitas Zig benar-benar keren

  • Hebat!
    Apakah ada formatter TS/JS yang bekerja seperti ini?
    Saya punya proyek yang memakai maplibre-gl, dan ekspresi spesifikasi style-nya kadang diformat berlebihan sampai tidak kelihatan apa-apa
    Sekarang saya berhenti memakai formatter, tapi karena terus debugging, menyalin, dan memberi komentar pada kode, jadinya kode saya mulai berantakan
    Mungkin formatter Zig bisa dibuat untuk memformat bahasa lain juga :)

    • Prettier punya fitur yang mirip, tapi secara spesifik hanya untuk object literal dan pilihannya cuma antara “semua dalam satu baris” atau “setiap elemen di baris terpisah”
      Misalnya, tidak ada cara untuk menyuruh formatter menaruh empat elemen per baris
      Selain itu, kalau object literal menjadi terlalu panjang, pada akhirnya Prettier akan tetap mengubahnya ke format “setiap elemen di baris terpisah”, apa pun bentuk teks masukannya
  • Saya pernah kecewa dengan formatter yang ringan, yang pada dasarnya hanya memecah baris, jadi saya suka dan iri dengan gagasan bahwa fleksibilitas seperti ini bisa ada di dalam contoh yang lebih ketat :p
    Baru-baru ini saat menjawab pertanyaan di fedi tentang menulis dan memformat Lisp dengan font proporsional, saya sempat menyinggung varian s-expression yang memakai spasi bermakna, yaitu wisp, Readable/Sweet expressions, serta SRFI 119 dan 110
    Saya juga menambahkan pengamatan bahwa keluarga sintaks ini mengembalikan sebagian kendali atas pemenggalan baris lewat ekstensi notasi infiks opsional

  • Desainnya menarik, tapi saya tidak yakin saya menyukainya
    Formatter saya menanganinya dengan cara berbeda: formatter mengabaikan trailing comma saat menentukan format, lalu selalu menambahkan trailing comma jika hasilnya multiline dan selalu menghapus trailing comma jika satu baris
    Jadi tidak bisa “diarahkan”, tapi f(1, 2, 3) akan tetap diformat konsisten tanpa peduli ada atau tidaknya trailing comma, maupun jumlah dan jenis spasi antar token
    Tetap perlu ada tingkat pengarahan tertentu
    Misalnya, jika ada list literal panjang [<expr1>, <expr2>, ..., <expr100>], kebanyakan formatter akan menaruh satu ekspresi per baris, padahal bisa jadi Anda ingin menaruh sebanyak mungkin dalam satu baris
    Menentukan itu lewat trailing comma terasa aneh, dan secara umum pilihannya bisa jadi bukan 2 melainkan N
    Menurut saya atribut lebih cocok untuk tujuan seperti ini
    Misalnya, mungkin ini sudah ada, tapi bisa saja ada sesuatu seperti #[rustfmt::list_layout(flow)] di depan statement untuk memengaruhi format list literal di dalam statement tersebut
    Jika pengarahan terlalu banyak, itu justru merusak tujuan formatter untuk membuat format kode di seluruh ekosistem tetap konsisten dan mempermudah code review, jadi seharusnya dibatasi pada kasus tertentu saja
    List literal yang panjang menurut saya memang contoh yang benar-benar layak
    Di proyek saya juga ada contoh ketika format membantu review expected value pada test, seperti ini
    Saya juga teringat satu perilaku “pengarah” lain di formatter Dart: pada list literal panjang, Anda bisa menambahkan baris komentar untuk mengelompokkan baris
    Misalnya, untuk [1, 2, 3, ..., 1000], formatter akan menaruh tiap elemen di baris terpisah, tapi Anda bisa mengelompokkannya secara manual seperti ini

    [1, 2, 3, 4, 5,  //  
     6, 7, 8, 9, 10, //  
     ...]  
    

    Saya tidak tahu apakah fitur seperti ini memang disengaja, atau hanya efek samping dari cara komentar diperlakukan

    • Cara itu persis seperti perilaku rustfmt, dan itu yang membuat saya gila
      Kadang ada kasus ketika batas panjang baris boleh saja terlewati karena pemanggilan fungsi justru lebih mudah dibaca kalau tidak dipecah, dan saya ingin bisa mencerminkan penilaian saya soal itu
      Satu contoh yang terpikir adalah OpenGL
      Biasanya saat memodifikasi atau memakai satu resource, misalnya inisialisasi tekstur, kita akan menulis banyak pemanggilan gl.* secara berurutan, tapi rustfmt mendorong pemecahan baris tanpa rasa apa pun selain tujuan robotik “baris terlalu panjang, harus dipecah”
      Contoh ini dibuat-buat untuk menunjukkan perilakunya dan tidak sepenuhnya sama dengan perilaku rustfmt yang sebenarnya
      Barisnya juga tidak sepanjang itu
      Saya sedang mengetik dari ponsel sekarang, jadi tidak punya alat untuk membuat contoh yang 100% akurat
      gl.bind_texture(gl::TEXTURE_2D, tex);  
      gl.tex_parameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST);  
      gl.tex_parameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
      
      // -->
      
      gl.bind_texture(gl::TEXTURE_2D, tex);  
      gl.tex_parameteri(  
          gl::TEXTURE_2D,  
          gl::TEXTURE_MIN_FILTER,  
          gl::NEAREST,  
      );  
      gl.tex_parameteri(  
          gl::TEXTURE_2D,  
          gl::TEXTURE_MAG_FILTER,  
          gl::NEAREST,  
      );  
      
      Memecah rangkaian pemanggilan gl.tex_parameteri seperti ini ke banyak baris sebenarnya lebih buruk, karena tiap pemanggilan justru lebih baik ditampilkan penuh dalam satu baris
      Jika kolomnya sejajar, perbedaan antara dua baris jadi jauh lebih mudah dilihat
      Versi yang dipecah mengurangi kedekatan visual dan lebih sulit dibaca
      Mata jadi tidak bisa membandingkan dua baris itu dengan mudah
      Ada juga kejadian lucu ketika formatter gagal total saat tidak bisa memformat sesuatu agar muat dalam batas jumlah karakter
      Ini sering terjadi saat menulis kode compiler dan membuat pesan diagnostik sebagai string literal, karena pesannya bisa cukup panjang
      rustfmt tidak tahu bagaimana membaginya, lalu menyerah dan tidak memformat seluruh statement itu sama sekali
      Seringnya bentuknya seperti ini
      match something {  
          // ... match arms above this one ...  
          _ => emit_diagnostic(&mut state, "This is a very long message to try and illustrate the problem. Help: please consult a doctor.")  
      }  
      
      Di sini, hanya karena pemanggilan emit_diagnostic itu berupa expression, ia menyerah memformat seluruh statement match, dan itu bodoh sekali
      Semua ini bisa dihindari kalau formatter tidak memaksa kode saya ke maksimum 100 kolom
  • Untuk orang yang, seperti saya, harus mencari tahu setelah melihat komentar di bagian akhir: ++ adalah operator konkatenasi array
    Jadi, kalau array dipecah menjadi dua, keduanya bisa diformat secara berbeda