Laporan Status Musim Gugur Haxe

Pada tanggal 26 Oktober, Linz am Rhein (Jerman) menjadi tuan rumah konferensi mini HaxeUp Sessions 2019 yang didedikasikan untuk Haxe dan teknologi terkait. Dan acara terpentingnya adalah, tentu saja, rilis final Haxe 4.0.0 (pada saat publikasi, yaitu, setelah sekitar satu minggu, pembaruan 4.0.1 dirilis ). Dalam artikel ini, saya ingin menyampaikan kepada Anda terjemahan laporan pertama konferensi - sebuah laporan tentang pekerjaan yang dilakukan oleh tim Haxe untuk 2019.


gambar


Sedikit tentang penulis laporan:


Simon telah bekerja dengan Haxe sejak 2010, ketika dia masih mahasiswa dan menulis karya simulasi cairan di Flash. Implementasi dari simulasi semacam itu memerlukan akses konstan ke data yang menggambarkan keadaan partikel (pada setiap langkah lebih dari 100 pertanyaan dibuat ke array data tentang keadaan setiap sel dalam simulasi), sementara bekerja dengan array dalam ActionScript 3 tidak begitu cepat. Oleh karena itu, implementasi awal tidak bisa digunakan dan diperlukan untuk menemukan solusi untuk masalah ini. Dalam pencariannya, Simon menemukan sebuah artikel oleh Nicolas Kannass (pencipta Haxe) pada opkode Alkimia yang tidak berdokumen yang tidak tersedia menggunakan ActionScript, tetapi Haxe mengizinkannya untuk digunakan. Menulis ulang simulasi pada Haxe menggunakan opcodes, Simon mendapat simulasi yang berhasil! Jadi, berkat array yang lambat di ActionScript, Simon belajar tentang Haxe.


Sejak 2011, Simon bergabung dengan pengembangan Haxe, ia mulai mempelajari OCaml (di mana kompiler ditulis) dan membuat berbagai koreksi ke kompiler.


Dan sejak 2012, ia menjadi pengembang kompiler utama. Pada tahun yang sama, Yayasan Haxe dibentuk (sebuah organisasi yang tujuan utamanya adalah mengembangkan dan memelihara ekosistem Haxe, membantu komunitas menyelenggarakan konferensi, dan menyediakan layanan konsultasi), dan Simon menjadi salah satu pendiri bersama.


gambar


Pada 2014-2015, Simon mengundang Josephine Pertosa ke Yayasan Haxe, yang seiring waktu menjadi bertanggung jawab untuk menyelenggarakan konferensi dan hubungan masyarakat.


Pada 2016, Simon membuat presentasi pertamanya tentang Haxe , dan pada 2018 menyelenggarakan HaxeUp Sessions pertama .


gambar


Jadi apa yang terjadi di dunia Haxe selama 2019 yang lalu?


Pada bulan Februari dan Maret, 2 kandidat rilis keluar (4.0.0-rc1 dan 4.0.0-rc2)
Pada bulan April, Aurel Bili (sebagai magang) dan Alexander Kuzmenko (sebagai pengembang kompiler) bergabung dengan tim Haxe Foundation.


Pada bulan Mei, Haxe US Summit 2019 diadakan .
Pada bulan Juni, Haxe 4.0.0-rc3 dirilis. Dan pada bulan September - Haxe 4.0.0-rc4 dan Haxe 4.0.0-rc5.


gambar


Haxe tidak hanya kompiler, tetapi juga seluruh rangkaian berbagai alat, dan sepanjang tahun pengerjaan mereka juga terus dilakukan:
Berkat upaya Andy Lee, Haxe sekarang menggunakan Pipa Azure, bukan Travis CI dan AppVeyor. Ini berarti bahwa perakitan dan pengujian otomatis sekarang jauh lebih cepat.
Hugh Sanderson terus bekerja pada hxcpp (perpustakaan untuk mendukung C ++ di Haxe).
Tiba-tiba, pengguna Github terurou dan takashiski bergabung dengan pekerjaan tentang externs untuk Node.js.
Rudy Ges bekerja pada perbaikan dan peningkatan untuk mendukung target C #.
George Corney terus mendukung generator extern HTML.
Jens Fisher sedang mengerjakan vshaxe (perpanjangan untuk VS Code untuk bekerja dengan Haxe) dan pada banyak proyek terkait Haxe lainnya.


gambar


Dan acara utama tahun ini, tentu saja, adalah rilis Haxe 4.0.0 yang telah lama ditunggu-tunggu (serta neko 2.3.0), yang secara tidak sengaja bertepatan dengan HaxeUp 2019 Linz :)


gambar


Simon mencurahkan sebagian besar laporan untuk fitur-fitur baru di Haxe 4.0.0 (Anda juga dapat mempelajarinya dari laporan Alexander Kuzmenko dari Haxe US Summit 2019 yang terakhir).


gambar


Eval macro interpreter baru beberapa kali lebih cepat daripada yang lama. Simon berbicara tentang dia secara rinci dalam pidatonya di Haxe Summit EU 2017 . Tetapi sejak itu telah meningkatkan kemampuan debugging kode, memperbaiki banyak bug, mendesain ulang implementasi string.


gambar


Haxe 4 memperkenalkan dukungan Unicode untuk semua platform (kecuali Neko). Simon menggambarkan hal ini secara terperinci dalam pidatonya tahun lalu . Untuk pengguna akhir dari kompiler, ini berarti ungkapan "Haxeは最高だぞ!".length untuk semua platform akan selalu kembali 10 (lagi, kecuali untuk Neko).


Pengkodean UCS-2 didukung minimal (pengkodean yang didukung secara native digunakan untuk setiap platform / bahasa; mencoba untuk mendukung pengodean yang sama di mana-mana tidak praktis):


  • JavaScript, Flash, HashLink dan C ++ menggunakan pengkodean UCS-2
  • untuk eval, PHP, lua - UTF-8
  • untuk Java dan C # - UTF-16
  • untuk Python - UTF-32

Semua karakter yang berada di luar bidang multibahasa utama (termasuk emoji) direpresentasikan sebagai "pasangan pengganti" - karakter tersebut diwakili oleh dua byte. Misalnya, jika dalam Java / C # / JavaScript (yaitu, untuk string dalam pengkodean UTF-16 dan UCS-2) untuk meminta panjang string yang terdiri dari satu emoji, hasilnya akan menjadi "2". Fakta ini harus diperhitungkan saat bekerja dengan string semacam itu pada platform ini.


Haxe 4 memperkenalkan jenis iterator baru - nilai kunci:


gambar


Ini bekerja dengan kontainer tipe Map (kamus) dan string (menggunakan kelas StringTools), dukungan untuk array belum diimplementasikan. Dimungkinkan juga untuk mengimplementasikan iterator seperti itu untuk kelas kustom, untuk ini cukup menerapkan metode keyValueIterator():KeyValueIterator<K, V> untuk mereka keyValueIterator():KeyValueIterator<K, V> .


Tag meta baru @:using memungkinkan Anda untuk mengaitkan ekstensi statis dengan tipe di tempat deklarasi mereka.


Pada contoh di bawah ini, enumerasi MyOption dikaitkan dengan MyOptionTools , jadi kami secara statis memperluas enumerasi ini (yang tidak mungkin dalam situasi biasa) dan mendapatkan kesempatan untuk memanggil metode get() , merujuknya sebagai metode objek.


gambar


Dalam contoh ini, metode get() inline, yang juga memungkinkan kompiler untuk lebih mengoptimalkan kode: alih-alih memanggil metode MyOptionTools.get(myOption) , kompiler akan menggantikan nilai yang disimpan, mis. 12 .


Jika metode ini tidak dinyatakan sebagai embeddable, maka alat optimasi lain yang tersedia untuk programmer adalah untuk menanamkan fungsi di tempat panggilan mereka (call-site inlining). Untuk melakukan ini, saat memanggil fungsi, Anda juga harus menggunakan inline :


gambar


Berkat karya Daniil Korostelev , Haxe sekarang memiliki kesempatan untuk menghasilkan kelas ES6 untuk JavaScript. Yang perlu Anda lakukan hanyalah menambahkan flag kompilasi -D js-es=6 .


Saat ini, kompiler menghasilkan satu file js untuk seluruh proyek (mungkin di masa depan untuk menghasilkan file js terpisah untuk masing-masing kelas, tetapi sejauh ini ini hanya dapat dilakukan dengan menggunakan alat tambahan ).


gambar


Untuk enumerasi abstrak, nilai sekarang dihasilkan secara otomatis.


Di Haxe 3, perlu untuk menetapkan nilai secara manual untuk setiap konstruktor. Dalam Haxe 4, enumerasi abstrak yang dibuat di atas Int berperilaku sesuai dengan aturan yang sama seperti dalam C. Enumerasi abstrak yang dibuat di atas string berperilaku sama - bagi mereka, nilai yang dihasilkan akan bertepatan dengan nama konstruktor.


gambar


Beberapa perbaikan sintaks juga perlu disebutkan:


  • enumerasi abstrak dan fungsi extern telah menjadi anggota penuh Haxe dan sekarang Anda tidak perlu menggunakan @:enum dan @:extern meta tag untuk menyatakannya
  • 4th Haxe menggunakan sintaks persimpangan tipe baru yang lebih baik mencerminkan esensi dari struktur yang diperluas. Konstruksi seperti itu paling berguna ketika mendeklarasikan struktur data: ekspresi typedef T = A & B berarti bahwa struktur T memiliki semua bidang yang ada dalam tipe A dan B
  • sama halnya, empat menyatakan batasan parameter tipe: entri <T:A & B> menunjukkan bahwa tipe parameter T harus A dan B
  • sintaks lama akan berfungsi (kecuali sintaksis untuk batasan jenis, karena akan bertentangan dengan sintaks baru untuk menggambarkan tipe fungsi)

gambar


Sintaks baru untuk menggambarkan tipe fungsi (sintaks tipe fungsi) lebih logis: menggunakan tanda kurung di sekitar tipe argumen fungsi secara visual lebih mudah dibaca. Selain itu, sintaks baru memungkinkan Anda untuk menentukan nama argumen, yang dapat digunakan sebagai bagian dari dokumentasi untuk kode (meskipun itu tidak mempengaruhi pengetikan itu sendiri).


gambar


Dalam kasus ini, sintaks lama terus didukung dan tidak ditinggalkan, seperti jika tidak, itu akan memerlukan terlalu banyak perubahan dalam kode yang ada (Simon sendiri terus-menerus menemukan dirinya keluar dari kebiasaan dan terus menggunakan sintaksis lama).


Haxe 4 akhirnya memiliki fungsi panah (atau ekspresi lambda)!


gambar


Fitur fungsi panah di Haxe adalah:


  • return implisit. Jika fungsi tubuh terdiri dari satu ekspresi, maka fungsi ini secara implisit mengembalikan nilai ekspresi ini
  • dimungkinkan untuk mengatur jenis argumen fungsi, karena kompiler tidak selalu dapat menentukan jenis yang diperlukan (mis. Float atau Int )
  • jika bodi fungsi terdiri dari beberapa ekspresi, maka Anda harus mengelilinginya dengan kurung kurawal
  • tetapi tidak ada cara untuk secara eksplisit mengatur tipe kembalinya fungsi

Secara umum, sintaks fungsi panah sangat mirip dengan yang digunakan di Java 8 (meskipun bekerja agak berbeda).


Dan karena kita menyebutkan Java, harus dikatakan bahwa dalam Haxe 4 menjadi mungkin untuk menghasilkan bytecode JVM secara langsung. Untuk melakukan ini, ketika menyusun proyek di bawah Java, tambahkan saja flag -D jvm .


Menghasilkan bytecode JVM berarti bahwa tidak perlu menggunakan kompiler Java, dan proses kompilasi jauh lebih cepat.


gambar


Sejauh ini, target JVM memiliki status eksperimental karena alasan berikut:


  • dalam beberapa kasus, bytecode sedikit lebih lambat daripada hasil menerjemahkan Haxe di Jawa dan kemudian dikompilasi dengan javac. Tetapi tim penyusun menyadari masalah dan tahu bagaimana memperbaikinya, itu hanya membutuhkan kerja tambahan.
  • ada masalah dengan MethodHandle di Android, yang juga membutuhkan pekerjaan tambahan (Simon akan senang jika dia membantu menyelesaikan masalah ini).

gambar


Perbandingan umum menghasilkan bytecode secara langsung (genjvm) dan mengkompilasi Haxe ke dalam kode Java, yang kemudian dikompilasi ke dalam bytecode (genjava):


  • seperti yang telah disebutkan, dalam hal kecepatan kompilasi, genjvm lebih cepat dari genjava
    dalam hal kecepatan eksekusi, bytecode genjvm masih kalah dengan genjava
  • ada beberapa masalah saat menggunakan parameter tipe dan genjava
  • genJvm menggunakan MethodHandle untuk merujuk ke fungsi, dan genjava menggunakan apa yang disebut "fungsi Waneck" (untuk menghormati Kaui Vanek , berkat dukungan Java dan C # yang muncul di Haxe). Meskipun kode yang diperoleh menggunakan fungsi-Waneck tidak terlihat cantik, ia bekerja dan bekerja cukup cepat.

Kiat umum untuk bekerja dengan Java di Haxe:


  • Karena fakta bahwa pengumpul sampah di Jawa cepat, masalah yang terkait dengannya jarang terjadi. Tentu saja, terus-menerus membuat objek baru bukanlah ide yang baik, tetapi Java melakukan pekerjaan yang baik dalam mengelola memori dan kebutuhan untuk terus menjaga alokasi tidak separah pada beberapa platform lain yang didukung oleh Haxe (misalnya, di HashLink)
  • mengakses bidang kelas dalam target jvm dapat bekerja sangat lambat jika ini dilakukan melalui struktur ( typedef ) - sedangkan kompiler tidak dapat mengoptimalkan kode tersebut
  • penggunaan kata kunci inline berlebihan harus dihindari - kompiler JIT melakukan pekerjaan yang cukup baik
  • Hindari penggunaan Null<T> , terutama saat berhadapan dengan perhitungan matematika yang rumit. Kalau tidak, banyak pernyataan kondisional akan muncul dalam kode yang dihasilkan, yang akan berdampak negatif pada kecepatan kode Anda.

Fitur Haxe 4 baru, Null safety, dapat membantu menghindari penggunaan Null<T> . Alexander Kuzmenko berbicara secara rinci tentang dia di HaxeUp tahun lalu .


gambar


Pada contoh pada slide di atas, metode static safe() memiliki mode Strict untuk memeriksa keamanan Null diaktifkan, dan metode ini memiliki parameter arg opsional, yang dapat memiliki nilai nol. Agar fungsi ini berhasil dikompilasi, pemrogram perlu menambahkan tanda centang pada nilai argumen arg (jika tidak, kompiler akan menampilkan pesan tentang ketidakmungkinan memanggil metode charAt() pada objek yang berpotensi nol).


gambar


Keamanan kosong dapat dikonfigurasi baik pada tingkat paket (menggunakan makro) dan tipe dan bidang individual objek (menggunakan tag meta @:nullSafety ).


Mode di mana Null Security bekerja adalah: Strict, Loose, dan Off. Secara global, pemeriksaan ini dinonaktifkan (Off-mode). Ketika diaktifkan, mode Longgar digunakan secara default (kecuali jika Anda secara eksplisit menentukan mode). Perbedaan utama antara mode Loose dan Strict adalah bahwa mode Loose mengabaikan kemungkinan perubahan nilai antara operasi mengakses nilai-nilai ini. Pada contoh pada slide di bawah ini, kita melihat bahwa cek null telah ditambahkan untuk variabel x . Namun, dalam mode Ketat, kode ini tidak dapat dikompilasi, karena sebelum bekerja secara langsung dengan variabel x , metode sideEffect() , yang berpotensi menihilkan nilai variabel ini, jadi Anda perlu menambahkan tanda centang lain atau menyalin nilai variabel ke variabel lokal, yang akan terus kami kerjakan.


gambar


Haxe 4 memperkenalkan kata kunci final baru, yang memiliki arti berbeda tergantung pada konteksnya:


  • jika Anda menggunakannya sebagai ganti kata kunci var , bidang yang dideklarasikan dengan cara ini tidak dapat diberi nilai baru. Anda hanya dapat mengaturnya secara langsung ketika mendeklarasikan (untuk bidang statis) atau dalam konstruktor (untuk bidang non-statis)
  • jika Anda menggunakannya saat mendeklarasikan sebuah kelas, itu akan melarang warisan darinya
  • jika Anda menggunakannya sebagai pengubah untuk mengakses properti objek, maka ini melarang redefinisi pengambil / penyetel di kelas turunan.

gambar


Secara teoritis, kompiler, setelah memenuhi kata kunci final , dapat mencoba mengoptimalkan kode, dengan asumsi bahwa nilai bidang ini tidak berubah. Tetapi untuk saat ini, kemungkinan ini hanya dipertimbangkan dan tidak diimplementasikan dalam kompiler.


gambar


Dan sedikit tentang masa depan Haxe:


  • saat ini bekerja pada API I / O asinkron
    Dukungan Coroutine sudah direncanakan, tetapi sejauh ini, pekerjaan mereka masih terhambat pada tahap perencanaan. Mungkin mereka akan muncul di Haxe 4.1, dan mungkin nanti.
  • optimasi tail-call akan muncul di kompiler
  • dan mungkin fungsi yang tersedia di tingkat modul . Meskipun prioritas fitur ini terus berubah

Source: https://habr.com/ru/post/id474452/


All Articles