Pengalaman Pengembangan Nim Saya


Halo, Habr!


Untuk beberapa waktu sekarang saya telah menulis kerangka permainan saya - sebuah proyek kesayangan untuk jiwa. Dan karena untuk jiwa Anda perlu memilih sesuatu yang Anda sukai (dan dalam hal ini, apa yang ingin Anda tulis), pilihan saya jatuh pada nim. Dalam artikel ini saya ingin berbicara secara khusus tentang nim, tentang fitur-fiturnya, pro dan kontra, dan tema gamedev hanya menetapkan konteks pengalaman saya - tugas apa yang saya selesaikan, kesulitan apa yang muncul.


Suatu ketika, ketika rumput lebih hijau dan langit lebih bersih, saya bertemu nim. Tidak, tidak seperti itu. Sekali waktu, saya ingin mengembangkan game untuk menulis game paling keren - saya pikir banyak yang melewati ini. Pada masa itu, Unity dan Unreal Engine baru saja mulai muncul di persidangan dan, sepertinya, belum gratis. Saya tidak menggunakannya, bukan karena keserakahan, tetapi karena keinginan untuk menulis semuanya sendiri, untuk menciptakan dunia permainan sepenuhnya dari awal, dari awal yang pertama nol byte. Ya, untuk waktu yang lama, ya, itu sulit, tetapi proses itu sendiri membawa kesenangan - tetapi apa lagi yang dibutuhkan untuk kebahagiaan?


Berbekal Straustrup dan Qt, saya minum kotoran untuk yang paling baik, karena, pertama, saya bukan salah satu dari 10 orang di dunia yang tahu C ++ dengan baik , dan kedua, plus aktif menempatkan tongkat di roda saya. Saya tidak melihat alasan untuk mengulang apa yang sudah ditulis platoff untuk saya:


Bagaimana saya menemukan bahasa pemrograman terbaik di dunia. Bagian 1
Bagaimana saya menemukan bahasa pemrograman terbaik di dunia. Bagian 2
Bagaimana saya menemukan bahasa pemrograman terbaik di dunia. Bagian Yo (2.72)


Ini adalah desas-desus gila ketika Anda menulis kode dengan bebas, hampir tanpa berpikir, tanpa menunggu core dibuang sebelum setiap peluncuran, ketika fitur ditambahkan tepat di depan mata kita, sekarang kita dapat melakukannya, dan sekarang seperti itu, katakan padaku tolong, apa bedanya bagi saya Saya tidak punya template jika saya tidak ketinggalan? Produktivitas adalah tujuan utama programmer yang melakukan sesuatu, dan satu-satunya tugas alat yang ia gunakan.

Ketika bekerja dengan C ++, saya terus-menerus berpikir bagaimana menulis apa yang saya inginkan, dan bukan apa yang harus saya tulis. Jadi saya beralih ke nim. Ceritanya sudah berakhir, izinkan saya berbagi pengalaman saya dengan Anda setelah beberapa tahun di nim.


Informasi umum untuk mereka yang tidak tahu


  • Open Source Compiler (MIT), yang dikembangkan oleh para penggemar. Pencipta bahasanya adalah Andreas Rumpf (Araq). Pengembang kedua adalah Dominik Picheta (dom96), yang menulis buku Nim saat beraksi . Juga, beberapa waktu lalu, Status mulai mensponsori pengembangan bahasa, jadi nim mendapat 2 pengembang penuh waktu. Selain mereka, tentu saja, orang lain akan berkontribusi.
  • Versi 1.0 baru-baru ini telah dirilis , yang berarti bahasanya stabil dan "memecah perubahan" tidak lagi diharapkan. Jika sebelumnya Anda tidak ingin menggunakan versi yang tidak stabil, karena pembaruan dapat merusak aplikasi, maka sekarang saatnya untuk mencoba nim di proyek Anda.
  • Nim mengkompilasi (atau mentransposisi) dalam C, C ++ (yang selanjutnya dikompilasi ke dalam kode asli) atau JS (dengan beberapa batasan). Dengan demikian, dengan bantuan FFI, semua perpustakaan yang ada untuk C dan C ++ tersedia untuk Anda. Jika tidak ada paket yang diperlukan pada nim - cari s atau plus.
  • Bahasa terdekat adalah python (berdasarkan sintaks, sekilas) dan D (berdasarkan fungsi) - IMHO

Dokumentasi


Ini sebenarnya buruk. Masalahnya:


  1. Dokumentasi tersebar di berbagai sumber
  2. Dokumentasi sial tidak sepenuhnya menggambarkan semua fitur bahasa
  3. Dokumentasi terkadang terlalu ringkas.

Contoh: jika Anda ingin menulis aplikasi multi-utas, ada banyak inti, tetapi tidak ada tempat lain.
Berikut adalah bagian dokumentasi resmi tentang stream . Tidak, Anda tahu, utas merupakan bagian utama yang terpisah dari bahasa, fitur yang bahkan perlu Anda sertakan dengan --threads:on flag saat dikompilasi. Di sana, tumpukan bersama atau thread-lokal tergantung pada pengumpul sampah, semua jenis memori bersama dan kunci, keamanan benang, modul bersama khusus, dan neraka tahu apa lagi. Bagaimana saya tahu semua tentang ini? Itu benar, dari buku nim dalam aksi, forum, stack overflow, TV dan dari tetangga, secara umum, dari mana saja, tetapi tidak dari dokumentasi resmi.


Atau ada yang disebut. "do notation" - berfungsi dengan sangat baik saat menggunakan templat, dll., secara umum di mana pun Anda perlu meneruskan panggilan balik atau hanya blok kode. Di mana saya bisa membacanya? Ya, dalam manual fitur eksperimental .


Setuju, mengumpulkan informasi tentang berbagai sumber tidak informatif masih menyenangkan. Jika Anda menulis di nim, Anda harus melakukannya.


Pada forum dan dalam masalah github, ada saran untuk meningkatkan dokumentasi, tetapi hal-hal tidak bergerak maju. Tampak bagi saya bahwa semacam tangan keras hilang, yang akan mengatakan "semuanya, komunitas, ambil sekop dan pergi untuk menyapu sekelompok ... potongan teks yang cerdik ini."


Untungnya, saya memukul sendiri, jadi saya mempersembahkan kepada Anda daftar juara nim


Dokumentasi


  • Tutorial 1 , Tutorial 2 - mulai dengan mereka
  • Nim in action adalah buku penjelasan yang benar-benar menjelaskan banyak aspek bahasa, terkadang jauh lebih baik daripada. dokumentasi
  • Manual nim - sebenarnya, manual - hampir semuanya dijelaskan, tapi tidak
  • Manual eksperimental Nim - mengapa tidak melanjutkan dokumentasi pada halaman terpisah?
  • Indeks - tautan ke semuanya dikumpulkan di sini, yaitu, secara umum semua yang dapat ditemukan di nim. Jika Anda tidak menemukan apa yang Anda butuhkan dalam tutorial dan manual, Anda pasti akan menemukannya dalam indeks.

Pelajaran dan Tutorial



Bantuan


  • IRC adalah habitat utama ... dari nimmers ?, yang disiarkan di Discord and Gitter . Saya belum pernah menggunakan IRC (dan masih belum menggunakannya). Secara umum, ini adalah pilihan yang sangat aneh. Masih ada surat merpati untuknya ... oke, bercanda.
  • Forum Nim Fitur forum minimal, tetapi 1) di sini Anda dapat menemukan jawabannya 2) di sini Anda dapat mengajukan pertanyaan jika item 1 tidak berfungsi 3) probabilitas jawaban lebih dari 50% 4) pengembang bahasa duduk di forum dan secara aktif merespons. Omong-omong, forum ditulis dalam nim, dan oleh karena itu tidak ada fungsi
  • Grup telegram Nim - dimungkinkan untuk mengajukan pertanyaan dan [tidak] mendapatkan jawaban.
  • Ada juga grup telegram Rusia, jika Anda bosan dengan nim dan tidak ingin mendengar apa pun tentangnya, Anda harus pergi ke sana :) (sebagian bercanda)

Taman bermain


  • Nim playground - di sini Anda dapat menjalankan program di nim langsung di browser
  • Kompilasi silang Nim docker - di sini Anda dapat membaca cara meluncurkan gambar buruh pelabuhan dan mengkompilasi program untuk berbagai platform.

Paket



Beralih ke nim dari bahasa lain



Apa yang kamu suka


Tidak masuk akal untuk mendaftar semua fitur bahasa, tetapi di sini ada beberapa fitur:


Kompleksitas fraktal


Nim memberi Anda "fraktal kompleksitas." Anda dapat menulis kode tingkat tinggi. Anda dapat menggunakan pointer mentah dan menikmati setiap attempt to read from nil . Anda dapat menyematkan kode C. Anda dapat menulis sisipan di assembler . Anda dapat menulis prosedur (pengiriman statis). Tidak cukup - ada "metode" (pengiriman dinamis). Lebih? Ada obat generik, dan ada obat generik yang meniru fungsi. Ada template - mekanisme penggantian, tetapi tidak muntah seperti di C ++ (apakah ada makro di sini - apakah itu hanya penggantian teks, atau apakah itu sesuatu yang lebih pintar?). Ada makro, pada akhirnya - itu seperti IDDQD, mereka mengaktifkan mode dewa dan memungkinkan Anda untuk bekerja secara langsung dengan AST dan secara harfiah mengganti potongan-potongan pohon sintaksis, atau memperluas bahasa sendiri sesuka Anda.
Artinya, pada level "tinggi", Anda dapat menulis kata-kata kunci dan kesedihan untuk tidak tahu, tetapi tidak ada yang melarang Anda untuk melakukan penipuan dengan kompleksitas apa pun.


Kecepatan pengembangan


Kurva belajar bukan kurva. Ini langsung. Dengan menginstal nim, Anda akan memulai dunia halo pertama Anda di menit pertama, dan pada hari pertama Anda akan menulis utilitas sederhana. Tetapi dalam beberapa bulan Anda akan memiliki sesuatu untuk dipelajari. Misalnya, saya mulai dengan prosedur, kemudian saya membutuhkan metode, setelah beberapa saat obat generik sangat berguna bagi saya, baru-baru ini saya menemukan templat dengan kemuliaan penuh, dan pada saat yang sama saya tidak menyentuh makro sama sekali. Dibandingkan dengan karat atau c ++ yang sama, menggabungkan dengan nim jauh lebih mudah.


Manajemen paket


Ada manajer paket bernama gesit yang dapat menginstal, mencopot, membuat paket dan memuat dependensi. Ketika Anda membuat paket Anda (= proyek), Anda dapat menulis tugas yang berbeda dengan gesit (menggunakan nimscript, yang merupakan subset dari nim yang dapat dieksekusi di VM), misalnya, membuat dokumentasi, menjalankan tes, menyalin aset, dll. Cekatan tidak hanya menempatkan dependensi yang diperlukan, tetapi juga memungkinkan Anda untuk mengkonfigurasi lingkungan kerja untuk proyek Anda. Yaitu, lincah, secara kasar, CMake, yang ditulis bukan oleh orang mesum, tetapi oleh orang normal.


Keterbacaan dan ekspresi


Secara eksternal, nim sangat mirip dengan python dengan anotasi tipe, walaupun nim sama sekali bukan python. Para pythonis harus melupakan pengetikan dinamis, pewarisan, dekorator, dan kesenangan lainnya, dan umumnya merestrukturisasi pemikiran mereka. Jangan mencoba mentransfer pengalaman python Anda ke nim, karena perbedaannya terlalu besar. Pada awalnya, saya benar-benar ingin koleksi dan mixin heterogen dengan dekorator. tapi entah bagaimana Anda terbiasa hidup dalam kesulitan :)


Berikut ini adalah contoh program nim:


  type NumberGenerator = object of Service # this service just generates some numbers NumberMessage = object of Message number: int proc run(self: NumberGenerator) = if not waitAvailable("calculator"): echo "Calculator is unavailable, shutting down" return for number in 0..<10: echo &"Sending number {number}" (ref NumberMessage)(number: number).send("calculator") 

Modularitas


Semuanya dibagi menjadi modul yang dapat Anda impor sesuka Anda - untuk mengimpor hanya karakter tertentu, atau semua kecuali tertentu, atau semua, atau tidak ada dan memaksa pengguna untuk menentukan path lengkap a la module.function() , dan juga mengimpor dengan nama yang berbeda. Tentu saja, semua variasi ini sangat berguna sebagai argumen lain dalam perdebatan "bahasa pemrograman mana yang lebih baik", yah, dalam proyek Anda, Anda akan dengan tenang menulis import mymodule - import mymodule dan tidak mengingat opsi lain.


Sintaks pemanggilan metode


Panggilan fungsi dapat direkam dengan berbagai cara:


  double(2) double 2 2.double() 2.double 

Di satu sisi, sekarang semua orang ... menulis sesuai keinginannya (dan semua orang suka dengan cara yang berbeda, tentu saja, dan dengan cara yang berbeda bahkan dalam kerangka satu proyek). Tetapi kemudian semua fungsi dapat ditulis sebagai pemanggilan metode, yang sangat meningkatkan keterbacaan. Dengan python, itu bisa:


 list(set(some_list)) # -:   ,     map  filter     

Kode yang sama di nim dapat ditulis ulang secara lebih logis:


 some_list.set.list #    

OOP


OOP, meskipun ada, berbeda dari itu dalam plus dan python: objek dan metode adalah entitas yang berbeda, dan mungkin ada dalam modul yang berbeda. Selain itu, Anda dapat menulis metode Anda untuk tipe dasar seperti int


  proc double(number: int): int = number * 2 echo $2.double() # prints "4" 

Di sisi lain, ada enkapsulasi di nim (aturan pertama modul di nim adalah untuk tidak memberi tahu siapa pun tentang pengidentifikasi tanpa tanda bintang). Berikut adalah contoh modul standar:


 # sharedtables.nim type SharedTable*[A, B] = object ## generic hash SharedTable data: KeyValuePairSeq[A, B] counter, dataLen: int lock: Lock 

Jenis SharedTable* ditandai dengan tanda bintang, yang berarti "terlihat" di modul lain dan dapat diimpor. Tapi di sini data , counter dan lock adalah anggota pribadi, dan sharedtables.nim tidak dapat diakses dari luar. Ini membuat saya sangat senang ketika saya memutuskan untuk menulis beberapa fungsi tambahan untuk tipe SharedTable , seperti len atau hasKey , dan menemukan bahwa saya tidak memiliki akses ke counter atau data , dan satu-satunya cara untuk "memperluas" SharedTable adalah dengan menulis sendiri , dengan bl


Secara umum, pewarisan digunakan jauh lebih jarang daripada di python yang sama (dari pengalaman pribadi), karena ada metode panggilan sintaks (lihat di atas) dan Varian Objek (lihat di bawah). Jalur nim adalah komposisi daripada warisan. Ini sama dengan polimorfisme: di nim ada metode yang dapat ditimpa dalam kelas penerus, tetapi ini harus secara eksplisit ditentukan pada kompilasi menggunakan --multimethods:on flag. Artinya, secara default, metode tidak berfungsi, yang sedikit mendorong pekerjaan tanpanya.


Eksekusi kompilasi waktu


Const - kemampuan untuk menghitung sesuatu pada tahap kompilasi dan "menjahit" ke dalam biner yang dihasilkan. Itu keren dan nyaman. Secara umum, nim memiliki hubungan khusus dengan "waktu kompilasi", bahkan ada kata kunci when - rasanya seperti, tetapi perbandingannya adalah pada tahap kompilasi. Anda dapat menulis sesuatu seperti


  when defined(SDL_VIDEO_DRIVER_WINDOWS): import windows ## oldwinapi lib elif defined(SDL_VIDEO_DRIVER_X11): import x11/x, x11/xlib ## x11 lib 

Ini sangat mudah, meskipun ada batasan pada apa yang dapat Anda lakukan pada tahap kompilasi (misalnya, Anda tidak dapat melakukan panggilan FFI).


Jenis referensi


Jenis ref - analog dari shared_ptr dalam C ++, yang akan ditangani oleh pemulung. Tetapi Anda juga dapat menghubungi pengumpul sampah sendiri pada saat-saat yang nyaman bagi Anda. Atau Anda dapat mencoba berbagai opsi untuk pengumpul sampah. Atau Anda dapat menonaktifkan pengumpul sampah sama sekali dan menggunakan pointer biasa.


Idealnya, jika Anda tidak menggunakan pointer mentah dan FFI, Anda tidak akan mendapatkan kesalahan segmentasi. Dalam praktiknya, sejauh ini tanpa FFI di mana pun.


Lambdas


Ada prosedur anonim (alias lambdas dalam python), tetapi tidak seperti python dalam prosedur anonim, Anda dapat menggunakan beberapa pernyataan:


 someProc(callback=proc(a: int) -> int = var b = 5*a; result = a) 

Pengecualian


Ada pengecualian, mereka sangat tidak nyaman untuk dilemparkan: python raise ValueError('bad value') , nim raise newException(ValueError, "bad value") . Tidak ada yang lebih aneh - cobalah, kecuali, akhirnya, semuanya seperti orang lain. Saya, sebagai pendukung pengecualian, bukan kode kesalahan, bersukacita. Ngomong-ngomong, Anda dapat menunjukkan untuk fungsi-fungsi yang pengecualiannya dapat dilemparkan, dan kompiler akan memeriksanya:


 proc p(what: bool) {.raises: [IOError, OSError].} = if what: raise newException(IOError, "IO") else: raise newException(OSError, "OS") 

Generik


Generik sangat ekspresif, misalnya, Anda dapat membatasi jenis yang mungkin


 proc onlyIntOrString[T: int|string](x, y: T) = discard #  int  string 

Dan Anda dapat mengirimkan tipe secara umum sebagai parameter - sepertinya fungsi biasa, tetapi sebenarnya generik:


 proc p(a: typedesc; b: a) = discard # is roughly the same as: proc p[T](a: typedesc[T]; b: T) = discard # hence this is a valid call: p(int, 4) # as parameter 'a' requires a type, but 'b' requires a value. 

Templat


Template adalah sesuatu seperti makro di C ++, baru saja dibuat dengan benar :) - Anda dapat dengan aman mentransfer seluruh blok kode ke template, dan tidak berpikir bahwa substitusi akan merusak sesuatu di kode luar (tapi Anda bisa, lagi , untuk membuatnya berantakan, jika Anda benar-benar perlu).


Berikut adalah contoh templat app , yang, bergantung pada nilai variabel, memanggil salah satu blok kode:


 template app*(serverCode: untyped, clientCode: untyped) = # ... case mode of client: clientCode of server: serverCode else: discard 

Dengan do saya bisa meneruskan seluruh blok ke template, misalnya:


 app do: # serverCode echo "I'm server" serverProc() do: # clientCode echo "I'm client" clientProc() 

Shell interaktif


Jika Anda perlu dengan cepat menguji sesuatu, yaitu, kemampuan untuk memanggil "interpreter" atau "nim shell" (seolah-olah Anda menjalankan python tanpa parameter). Untuk melakukan ini, gunakan perintah nim secret atau unduh paket inim .


Ffi


FFI - kemampuan untuk berinteraksi dengan perpustakaan pihak ketiga di C / C ++. Sayangnya, untuk menggunakan perpustakaan eksternal Anda harus menulis bungkus yang menjelaskan dari mana dan apa yang akan diimpor. Sebagai contoh:


 {.link: "/usr/lib/libOgreMain.so".} type ManualObjectSection* {.importcpp: "Ogre::ManualObject::ManualObjectSection", bycopy.} = object 

Ada alat yang membuat proses ini semi-otomatis:



Apa yang tidak suka


Kesulitan


Terlalu banyak hal. Bahasa itu dipahami sebagai minimalis, tetapi sekarang sangat jauh dari kebenaran. Sebagai contoh, mengapa kita mendapatkan penataan ulang kode ?!


Redundansi


Banyak omong kosong: system.addInt - "Mengubah integer ke representasi string dan menambahkannya ke hasil". Menurut saya ini adalah fungsi yang sangat nyaman, saya menggunakannya di setiap proyek. Ini satu lagi yang menarik: fileExists and existFile ( https://forum.nim-lang.org/t/3636 )


Tidak ada penyatuan


"Hanya ada satu cara untuk bertiga" - tidak ada sama sekali:


  • Sintaks panggilan metode - tulis panggilan fungsi seperti yang Anda inginkan
  • fmt vs &
  • camelCase dan underscore_notation
  • ini dan tHiS (spoiler: itu hal yang sama)
  • fungsi vs prosedur vs template

Bug (tidak ada TAS!)


Ada bug, sekitar 1400 . Atau hanya pergi ke forum - mereka terus - menerus menemukan beberapa bug.


Stabilitas


Selain paragraf sebelumnya, v1 menyiratkan stabilitas, kan? Dan di sini pencipta bahasa Araq terbang ke forum dan berkata: "dudes, saya punya pengumpul sampah (keenam) lain di sini, lebih dingin, lebih cepat, lebih muda, memberi Anda memori bersama untuk thread (ha ha, dan sebelum itu Anda menderita dan kruk bekas), unduh cabang pengembangan dan coba. " Dan semua itu, "Wow, keren sekali! Dan apa artinya itu bagi manusia biasa? Apakah kita sekarang perlu mengubah semua kode lagi?" Sepertinya tidak, jadi saya memperbarui nim, menjalankan pengumpul sampah baru --gc:arc dan program saya mogok di suatu tempat pada tahap kompilasi kode c ++ (mis. Tidak di nim, tetapi dalam gcc):


 /usr/lib/nim/system.nim:274:77: error: 'union pthread_cond_t' has no member named 'abi' 274 | result = x 

Hebat! Sekarang, alih-alih menulis kode baru, saya harus memperbaiki yang lama. Bukankah itu yang saya lari dari ketika saya memilih nim?


Senang mengetahui bahwa saya tidak sendirian


Metode dan Multithreading


Secara default, flag multimethods dan threads mati - Anda tidak akan melakukannya 2019 2020 menulis aplikasi multi-utas dengan metode utama ?! Dan betapa hebatnya jika perpustakaan Anda dibuat tanpa mempertimbangkan arus, dan kemudian pengguna menyalakannya ... Oh ya, ada pragma indah {.inheritable.} Dan {.base.} Untuk warisan sehingga kode Anda tidak terlalu ringkas.


Varian objek


Anda dapat menghindari warisan dengan menggunakan apa yang disebut varian objek:


 type CoordinateSystem = enum csCar, # Cartesian csCyl, # Cylindrical Coordinates = object case cs: CoordinateSystem: # cs is the coordinate discriminator of csCar: x: float y: float z: float of csCyl: r: float phi: float k: float 

Bergantung pada nilai cs , salah satu bidang x, y, z, atau r, phi dan k akan tersedia untuk Anda.


Apa kerugiannya?
Pertama, memori dicadangkan untuk "opsi terbesar" - sehingga dijamin sesuai dengan memori yang dialokasikan untuk objek.
Kedua, warisan masih lebih fleksibel - Anda selalu dapat membuat turunan dan menambahkan lebih banyak bidang, dan dalam varian objek semua bidang didefinisikan secara kaku dalam satu bagian.
Ketiga, yang paling membuat marah adalah Anda tidak bisa "menggunakan kembali" bidang dalam berbagai jenis:


 type # The 3 notations refer to the same 3-D entity, and some coordinates are shared CoordinateSystem = enum csCar, # Cartesian (x,y,z) csCyl, # Cylindrical (r,φ,z) Coordinates = object case cs: CoordinateSystem: # cs is the coordinate discriminator of csCar: x: float y: float z: float # z already defined here of csCyl: r: float phi: float z: float # fails to compile due to redefinition of z 

Lakukan notasi


Hanya mengutip :


  • lakukan dengan tanda kurung adalah proc anonim
  • lakukan tanpa tanda kurung hanya blok kode
    Satu ungkapan berarti hal-hal yang berbeda ¯_ (ツ) _ / ¯

Kapan harus digunakan


Jadi, kami memiliki fungsi, prosedur, generik, multimetode, templat, dan makro. Kapan lebih baik menggunakan templat, dan kapan prosedur? Templat atau generik? Fungsi atau prosedur? Jadi, bagaimana dengan makro? Saya pikir Anda mengerti maksudnya.


Pragma khusus


Ada dekorator dalam python yang dapat diterapkan bahkan ke kelas, bahkan ke fungsi.
Ada pragma di nim untuk ini. Dan inilah:


  • Anda dapat menulis pragma Anda sendiri yang akan menghiasi prosedur:
     proc fib(n : int) : int {.cached.} = # do smth 
  • Anda tidak dapat menulis pragma Anda sendiri yang akan menghias tipe (= kelas).

Lincah


Apa yang mati tidak bisa mati. Dalam gesit, banyak proyek yang belum diperbarui untuk waktu yang lama (dan dalam nim itu seperti kematian) - dan mereka tidak dihapus. Tidak ada yang mengikuti ini. Jelas, kompatibilitas ke belakang, "Anda tidak bisa hanya mengambil dan menghapus paket dari lobak", tetapi masih ... Oke, terima kasih, setidaknya tidak seperti npm.


Abstraksi bocor


Ada hukum abstraksi berlubang - Anda menggunakan semacam abstraksi, tetapi cepat atau lambat Anda akan menemukan "lubang" di dalamnya yang akan membawa Anda ke tingkat yang lebih rendah. Nim adalah abstraksi dari C dan C ++, dan cepat atau lambat Anda akan gagal di sana. Taruhan Anda tidak suka di sana?


 Error: execution of an external compiler program 'g++ -c -w -w -fpermissive -pthread -I/usr/lib/nim -I/home/user/c4/systems/network -o /home/user/.cache/nim/enet_d/@m..@s..@s..@s..@s..@s..@s.nimble@spkgs@smsgpack4nim-0.3.0@smsgpack4nim.nim.cpp:6987:136: note: initializing argument 2 of 'void unpack_type__k2dhaoojunqoSwgmQ9bNNug(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA*, NU&)' 6987 | N_LIB_PRIVATE N_NIMCALL(void, unpack_type__k2dhaoojunqoSwgmQ9bNNug)(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA* s, NU& val) { nimfr_("unpack_type", "/home/user/.nimble/pkgs/msgpack4nim-0.3.0/msgpack4nim.nim"); | tyObject_MsgStreamcolonObjectType ___ kto5qgghQl207nm2KQZEDA * s, NU & val) {nimfr _ ( "unpack_type", "/home/user/.nimble/pkgs/msgpack4nim-0.3.0/msgpack4nim.nim"); Error: execution of an external compiler program 'g++ -c -w -w -fpermissive -pthread -I/usr/lib/nim -I/home/user/c4/systems/network -o /home/user/.cache/nim/enet_d/@m..@s..@s..@s..@s..@s..@s.nimble@spkgs@smsgpack4nim-0.3.0@smsgpack4nim.nim.cpp:6987:136: note: initializing argument 2 of 'void unpack_type__k2dhaoojunqoSwgmQ9bNNug(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA*, NU&)' 6987 | N_LIB_PRIVATE N_NIMCALL(void, unpack_type__k2dhaoojunqoSwgmQ9bNNug)(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA* s, NU& val) { nimfr_("unpack_type", "/home/user/.nimble/pkgs/msgpack4nim-0.3.0/msgpack4nim.nim"); | 

 /usr/bin/ld: /home/user/.cache/nim/enet_d/stdlib_dollars.nim.cpp.o: in function `dollar___uR9bMx2FZlD8AoPom9cVY9ctA(tyObject_ConnectMessage__e5GUVMJGtJeVjEZUTYbwnA*)': stdlib_dollars.nim.cpp:(.text+0x229): undefined reference to `resizeString(NimStringDesc*, long)' /usr/bin/ld: stdlib_dollars.nim.cpp:(.text+0x267): undefined reference to `resizeString(NimStringDesc*, long)' /usr/bin/ld: stdlib_dollars.nim.cpp:(.text+0x2a2): undefined reference to `resizeString(NimStringDesc*, long)' 

Jadi


Saya seorang programmer bodoh. Saya tidak ingin tahu cara kerja GC, apa yang ada di sana dan bagaimana itu terhubung, di mana itu di-cache dan bagaimana sampah dibuang. Ini seperti mobil - pada prinsipnya, saya tahu cara kerjanya, sedikit tentang perataan roda, sedikit tentang gearbox, saya perlu mengisi oli dan sebagainya, tetapi secara umum saya hanya ingin duduk dan pergi (dan berpuasa) ke pesta. Mesin bukanlah tujuan, tetapi sarana untuk mencapai tujuan. Jika rusak, saya tidak ingin masuk ke kap, tetapi bawa saja ke layanan (dalam arti, saya akan membuka masalah di github), dan akan lebih baik jika mereka memperbaikinya dengan cepat.


Nim seharusnya menjadi mesin seperti itu. Sebagian, dia menjadi, tetapi pada saat yang sama, ketika saya bergegas di sepanjang jalan raya dengan mobil ini, roda saya jatuh, dan kaca spion mengarah ke depan. Para insinyur mengejar saya dan menempelkan sesuatu dengan cepat ("sekarang mobil Anda bahkan lebih cepat dengan spoiler baru ini"), tetapi dari sini bagasi jatuh. Dan tahukah Anda? Saya masih sangat suka mobil ini, karena ini adalah yang terbaik dari semua mobil yang saya lihat.

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


All Articles