Julia: Tinjauan konsistensi API

Dibuat pada 2 Feb 2017  ·  131Komentar  ·  Sumber: JuliaLang/julia

Saya memulai ini sebagai tempat untuk meninggalkan catatan tentang hal-hal yang perlu dipertimbangkan saat memeriksa konsistensi API di Julia 1.0.

  • [x] Prioritas konvensi. Membuat daftar dan memprioritaskan konvensi what-come-first kami dalam hal argumen fungsi untuk blok-do, argumen IO untuk fungsi yang dicetak, keluaran untuk fungsi di tempat, dll (https://github.com/JuliaLang/julia/issues/ 19150).

  • [] Argumen posisi vs kata kunci. Dulu kami tidak memiliki argumen kata kunci. Mereka terkadang masih dihindari karena pertimbangan kinerja. Kami harus membuat pilihan ini berdasarkan pada apa yang membuat API terbaik, bukan pada jenis bagasi historis tersebut (masalah kinerja kata kunci juga harus ditangani sehingga ini tidak lagi menjadi pertimbangan).

  • [] Alat metaprogramming. Kami memiliki banyak alat seperti @code_xxx yang dipasangkan dengan fungsi dasar seperti code_xxx . Ini harus berperilaku secara konsisten: tanda tangan serupa, jika ada fungsi dengan tanda tangan serupa, pastikan fungsi tersebut memiliki versi makro yang serupa. Idealnya, mereka semua harus mengembalikan nilai, daripada beberapa nilai kembali dan hasil pencetakan lainnya, meskipun itu mungkin sulit untuk hal-hal seperti kode LLVM dan kode perakitan.

  • [] IO <=> nama file yang setara. Kami biasanya mengizinkan nama file sebagai string untuk diteruskan sebagai pengganti objek IO dan perilaku standarnya adalah membuka file dalam mode yang sesuai, meneruskan objek IO yang dihasilkan ke fungsi yang sama dengan argumen yang sama, dan kemudian memastikan bahwa objek IO ditutup setelah itu. Pastikan semua fungsi penerima IO yang sesuai mengikuti pola ini.

  • [] Reducers API. Pastikan reduksi memiliki perilaku yang konsisten - semua menggunakan fungsi peta sebelum reduksi; argumen dimensi yang kongruen, dll.

  • [] Argumen dimensi. Perlakuan yang konsisten terhadap argumen input "hitung di seluruh dimensi [ini] ini", jenis apa yang diizinkan, dll., Pertimbangkan apakah melakukan hal ini sebagai argumen kata kunci yang mungkin diinginkan.

  • [] Pasangan yang bermutasi / tidak bermutasi. Periksa apakah fungsi non-mutasi dipasangkan dengan fungsi mutasi yang masuk akal dan sebaliknya.

  • [] Tuple vs. vararg. Periksa apakah ada konsistensi umum antara apakah fungsi menggunakan tupel sebagai argumen terakhir atau vararg.

  • [] Serikat vs. nullables vs. kesalahan. Aturan yang konsisten tentang kapan fungsi harus menampilkan kesalahan, dan kapan harus mengembalikan Nullable atau Unions (mis. Parse / tryparse, cocok, dll.).

  • [] Dukung generator seluas mungkin. Pastikan semua fungsi yang dapat bekerja dengan generator melakukannya. Kami sudah cukup mahir dalam hal ini, tetapi saya rasa kami melewatkan beberapa.

  • [] Pemilihan jenis keluaran. Bersikaplah konsisten tentang apakah API "tipe keluaran" harus dalam hal jenis elemen atau jenis penampung keseluruhan (ref # 11557 dan # 16740).

  • [x] Pilih nama. Ada beberapa fungsi / operator dengan alias. Saya pikir ini baik-baik saja dalam kasus di mana salah satu nama adalah non-ASCII dan versi ASCII disediakan sehingga orang masih dapat menulis kode ASCII murni, tetapi ada juga kasus seperti <: yang merupakan alias untuk issubtype kedua nama tersebut adalah ASCII. Kita harus memilih satu dan menghentikan yang lain. Kami menghentikan is mendukung === dan harus melakukan hal yang sama di sini.

  • [] Konsistensi dengan DataStructures . Ini agak di luar cakupan Base Julia, tetapi kita harus memastikan bahwa semua koleksi di DataStructures memiliki API yang konsisten dengan yang disediakan oleh Base. Hubungan ke arah lain adalah bahwa beberapa dari tipe tersebut dapat menginformasikan bagaimana kami akhirnya mendesain API di Base karena kami ingin mereka meluas dengan lancar dan konsisten.

  • [] NaN vs. Kesalahan Domain. Lihat https://github.com/JuliaLang/julia/issues/5234 - memiliki kebijakan kapan harus melakukannya dan pastikan dipatuhi secara konsisten.

  • [] Generator <=> koleksi. Terkadang Anda menginginkan koleksi, terkadang Anda menginginkan generator. Kita harus memeriksa semua API kita dan memastikan ada opsi untuk keduanya yang masuk akal. Dahulu kala, ada aturan untuk menggunakan nama huruf besar untuk versi generator dan nama huruf kecil untuk versi yang diinginkan dan mengembalikan koleksi baru. Tapi tidak ada yang memperhatikan itu, jadi mungkin kita perlu konvensi baru.

  • [] Fungsi urutan yang lebih tinggi pada asosiatif. Saat ini beberapa fungsi urutan yang lebih tinggi mengulangi koleksi asosiatif dengan tanda tangan (k,v) - misalnya map , filter . Yang lain mengulangi pasangan, yaitu dengan tanda tangan kv , mengharuskan tubuh untuk secara eksplisit merusak pasangan menjadi k dan v - misalnya all , any . Ini harus ditinjau dan dibuat konsisten.

  • [x] Konversi vs. membangun. Izinkan konversi jika sesuai. Misalnya, ada beberapa masalah / pertanyaan tentang convert(String, 'x') . Secara umum, konversi sesuai jika ada satu transformasi kanonik. Konversi string menjadi angka secara umum tidak tepat karena ada banyak cara tekstual untuk merepresentasikan angka, jadi kita perlu mengurai, dengan opsi. Namun, ada satu cara kanonik untuk merepresentasikan nomor versi sebagai string, jadi kami dapat mengonversinya. Kita harus menerapkan logika ini dengan hati-hati dan universal.

  • [] Tinjau kelengkapan API koleksi. Kita harus melihat fungsi perpustakaan standar untuk koleksi yang disediakan oleh bahasa lain dan memastikan kita memiliki cara untuk mengekspresikan operasi umum yang mereka miliki. Misalnya, kita tidak memiliki fungsi flatten atau fungsi concat . Kami mungkin harus.

  • [] Menggarisbawahi audit.

deprecation

Komentar yang paling membantu

Audit garis bawah

Berikut ini adalah analisis dari semua simbol yang diekspor dari Base yang berisi garis bawah, tidak digunakan lagi, dan bukan makro string. Hal utama yang perlu diperhatikan di sini adalah bahwa ini hanya nama yang diekspor; ini tidak termasuk nama yang tidak diekspor yang kami beri tahu orang-orang untuk menyebutnya memenuhi syarat.

Saya telah memisahkan hal-hal berdasarkan kategori. Semoga lebih bermanfaat daripada mengganggu.

Refleksi

Kami memiliki makro berikut dengan fungsi yang sesuai:

  • [] @code_llvm , code_llvm
  • [] @code_lowered , code_lowered
  • [] @code_native , code_native
  • [] @code_typed , code_typed
  • [] @code_warntype , code_warntype

Perubahan apa pun yang diterapkan ke makro, jika ada, harus diterapkan dengan cara yang sama ke fungsi.

  • [x] module_name -> nameof (# 25622)
  • [x] module_parent -> parentmodule (# 25629, lihat # 25436 untuk upaya sebelumnya dalam mengganti nama)
  • [x] method_exists -> hasmethod (# 25615)
  • [x] object_id -> objectid (# 25615)
  • [] pointer_from_objref

pointer_from_objref mungkin bisa dilakukan dengan nama yang lebih deskriptif, mungkin sesuatu seperti address ?

Alias ​​untuk interop C.

Jenis alias yang mengandung garis bawah adalah C_NULL , Cintmax_t , Cptrdiff_t , Csize_t , Cssize_t , Cuintmax_t , dan Cwchar_t . Yang diakhiri dengan _t harus tetap, karena mereka dinamai sesuai dengan tipe C yang sesuai.

C_NULL adalah yang aneh di sini, menjadi satu-satunya alias C yang berisi garis bawah yang tidak dicerminkan di C (karena di C ini hanya NULL ). Kami dapat mempertimbangkan untuk menyebut ini CNULL .

  • [] C_NULL

Sedikit menghitung

  • [] count_ones
  • [] count_zeros
  • [] trailing_ones
  • [] trailing_zeros
  • [] leading_ones
  • [] leading_zeros

Untuk diskusi tentang mengganti nama ini, lihat # 23531. Saya sangat menyukai menghapus garis bawah untuk ini, serta beberapa penggantian yang diusulkan dalam PR itu. Saya pikir itu harus dipertimbangkan kembali.

Operasi yang tidak aman

  • [] unsafe_copyto!
  • [] unsafe_load
  • [] unsafe_pointer_to_objref
  • [] unsafe_read
  • [] unsafe_store!
  • [] unsafe_string
  • [] unsafe_trunc
  • [] unsafe_wrap
  • [] unsafe_write

Mungkin tidak masalah untuk menyimpan ini sebagaimana adanya; keburukan garis bawah semakin menggarisbawahi ketidakamanan mereka.

Pengindeksan

  • [] broadcast_getindex
  • [] broadcast_setindex!
  • [] to_indices

Ternyata ada broadcast_getindex dan broadcast_setindex! . Saya tidak mengerti apa yang mereka lakukan. Mungkin mereka bisa menggunakan nama yang lebih deskriptif?

Menariknya, versi indeks tunggal to_indices , Base.to_index , tidak diekspor.

Jejak

  • [] catch_backtrace
  • [x] catch_stacktrace -> stacktrace(catch_backtrace()) (# 25615)

Agaknya ini adalah catch blok ekivalen backtrace dan stacktrace , masing-masing.

Tugas, proses, dan sinyal

  • [] current_task
  • [] task_local_storage
  • [] disable_sigint
  • [] reenable_sigint
  • [] process_exited
  • [] process_running

Aliran

  • [] redirect_stderr
  • [] redirect_stdin
  • [] redirect_stdout
  • [x] nb_available -> bytesavailable (# 25634)

Alangkah baiknya memiliki fungsi redirection IO -> IO lebih umum di mana semua ini dapat digabungkan, misalnya redirect(STDOUT, io) , sehingga menghapus garis bawah dan ekspor.

Promosi

  • [] promote_rule
  • [] promote_shape
  • [] promote_type

Lihat # 23999 untuk diskusi yang relevan tentang promote_rule .

Pencetakan

  • [x] print_with_color -> printstyled (lihat # 25522)
  • [] print_shortest (lihat # 25745)
  • [] escape_string (lihat # 25620)
  • [] unescape_string

escape_string dan unescape_string agak aneh karena mereka dapat mencetak ke aliran atau mengembalikan string. Lihat # 25620 untuk proposal untuk memindahkan / mengganti namanya.

Pemuatan kode

  • [] include_dependency
  • [] include_string

include_dependency . Apakah ini bahkan digunakan di luar Base? Saya tidak dapat memikirkan situasi di mana Anda menginginkan ini daripada include dalam skenario tipikal.

include_string . Bukankah ini hanya versi resmi dari eval(parse()) ?

Hal-hal yang tidak perlu saya kategorikan

  • [x] gc_enable -> GC.enable (# 25616)
  • [] get_zero_subnormals
  • [] set_zero_subnormals
  • [] time_ns

get_zero_subnormals dan set_zero_subnormals dapat dilakukan dengan nama yang lebih deskriptif. Apakah perlu diekspor?

Semua 131 komentar

Mohon maaf jika ini bukan tempat yang tepat untuk menyebutkan ini, tetapi alangkah baiknya jika kedepannya lebih konsisten dengan garis bawah dalam nama fungsi.

Tidak, ini tempat yang bagus untuk itu. Dan ya, kita harus berusaha untuk menghilangkan semua nama yang membutuhkan garis bawah :)

  • perlakuan yang konsisten dari argumen input "hitung di seluruh dimensi [ini] ini", jenis apa yang diizinkan, dll., pertimbangkan apakah melakukan hal ini sebagai argumen kata kunci yang mungkin diinginkan
  • membuat daftar dan memprioritaskan konvensi what-come-first kami dalam hal argumen fungsi untuk blok-do, argumen IO untuk fungsi yang dicetak, keluaran untuk fungsi di tempat, dll (edit: mengira mungkin sudah ada yang terbuka untuk ini)

Untuk poin kedua @tkelman , lihat https://github.com/JuliaLang/julia/issues/19150

Ada juga Julep baru-baru ini mengenai API untuk find dan fungsi terkait: https://github.com/JuliaLang/Juleps/blob/master/Find.md

Haruskah kita menghentikan put! dan take! pada saluran (dan mungkin melakukan hal yang sama untuk masa depan) karena kita memiliki push! dan shift! ? Hanya menyarankan untuk menghapus 2 kata yang berlebihan di API.

Saya curiga shift! ramah pengguna. Kandidat fetch! kita sudah memiliki fetch yang merupakan versi tidak bermutasi dari take!

ref # 13538 # 12469

@amitmurthy @malmaud

Edit: Bahkan masuk akal untuk menggunakan kembali send dan recv pada saluran. (Saya terkejut bahwa ini hanya digunakan untuk UDPSockets saat ini)

+1 untuk mengganti put! / take! dengan push! / fetch!

Saya akan menambahkan penggantian nama @inferred menjadi @test_inferred .

Periksa kembali apakah spesialisasi konsisten dengan fungsi yang lebih umum, yaitu bukan sesuatu seperti # 20233.

Tinjau semua fungsi yang diekspor untuk memeriksa apakah ada yang dapat dihilangkan dengan menggantinya dengan beberapa pengiriman, misalnya print_with_color

Pasangan tipikal adalah push! dan shift! saat bekerja dengan struktur data seperti antrian.

Jika kita tidak akan menggunakan penyandingan nama tipikal untuk jenis struktur data ini karena kita khawatir bahwa operasi tersebut memerlukan overhead komunikasi yang tidak cukup disampaikan oleh nama-nama itu, maka menurut saya push! masuk akal. send dan recv mungkin benar-benar lebih baik.

Mungkin periksa ulang apakah ada konsistensi umum antara apakah fungsi menggunakan tupel sebagai argumen terakhir atau vararg.

Mungkin terlalu besar untuk masalah ini, tetapi akan lebih baik untuk memiliki aturan yang konsisten tentang kapan fungsi harus menampilkan kesalahan, dan kapan mereka harus mengembalikan Nullable s atau Union s (mis. parse / tryparse , match , dll.)

Tidak masalah yang terlalu besar, @simonbyrne - ini adalah daftar cucian.

Btw: ini tidak benar-benar untuk perubahan tertentu (mis. Mengganti nama fungsi tertentu) - ini lebih tentang jenis hal yang dapat kita ulas. Untuk perubahan khusus yang diusulkan, cukup buka masalah yang mengusulkan perubahan itu.

Kami memiliki banyak alat seperti @code_xxx yang dipasangkan dengan fungsi dasar seperti code_xxx

Tidak yakin apakah ini yang Anda bicarakan, tetapi lihat CreateMacrosFrom.jl

  • Apakah API "jenis keluaran" harus dalam hal jenis elemen atau jenis penampung keseluruhan (ref # 11557 dan # 16740)
  • Mendokumentasikan semua fungsi yang diekspor (termasuk doctests)

Mendokumentasikan semua fungsi yang diekspor (termasuk doctests)

jika ini adalah bagian dari ini, maka mungkin juga: ingatlah untuk memberi label pengujian Anda dengan nomor terbitan / pr. Ini membuatnya lebih mudah untuk memahami mengapa tes itu ada. Saya tahu bagaimana git menyalahkan bekerja, tetapi ketika menambahkan testets (hanya untuk memberikan contoh) terkadang ada sedikit misteri apa yang sedang diuji, dan akan sangat bagus jika nomor masalah / pr selalu ada.

@dpsanders : dan makro yang diekspor! misal @fastmath tidak memiliki dokumen.

Ini sangat kecil, tetapi fungsi string dan Symbol melakukan hal yang hampir sama dan memiliki kapitalisasi yang berbeda. Saya pikir symbol akan lebih masuk akal.

@amellnik Perbedaannya adalah bahwa Symbol adalah konstruktor tipe dan string adalah fungsi biasa. IIRC kami dulu memiliki symbol tetapi tidak digunakan lagi untuk mendukung tipe konstruktor. Saya tidak yakin perubahan diperlukan untuk ini, tetapi jika ada yang menurut saya kita harus menggunakan konstruktor String sebagai pengganti string .

jika ada yang saya pikir kita harus menggunakan konstruktor String sebagai pengganti string.

Tidak, keduanya adalah fungsi yang berbeda dan tidak boleh digabungkan

julia> String(UInt8[])
""

julia> string(UInt8[])
"UInt8[]"

Tidak, keduanya adalah fungsi yang berbeda dan tidak boleh digabungkan

Ini terlihat seperti situasi di mana string(args...) seharusnya sudah tidak digunakan lagi demi sprint(print, args...) , lalu - memiliki string dan String membingungkan. Kami dapat mengkhususkan diri pada sprint(::typeof(print), args...) untuk memulihkan kinerja yang hilang. Sejalan dengan itu, mungkin juga masuk akal untuk menghentikan repr(x) untuk sprint(showall, args...) .

Kedengarannya oke meskipun memanggil string untuk mengubah sesuatu menjadi string tampaknya cukup standar ....

memanggil string untuk mengubah sesuatu menjadi string tampaknya cukup standar

Ya, tapi di situlah pemutusan hubungan antara String dan string masuk.

sprint(print, ...) terasa berlebihan. Jika kita menghilangkan string , kita dapat mengganti nama sprint menjadi string jadi kita mendapatkan string(print, foo) dan string(showall, foo) yang menurut saya bagus .

Ini mungkin kasus di mana konsistensi dinilai terlalu tinggi. Saya pikir tidak apa-apa memiliki string(x) untuk "beri saya representasi string x". Jika akan lebih rumit dari itu, misalnya meminta Anda menentukan fungsi pencetakan mana yang akan digunakan, maka menggunakan nama lain seperti sprint masuk akal.

Saya juga boleh mengganti nama String(UInt8[]) menjadi yang lain, dan menggunakan String bukan string . string memberi kita sedikit lebih banyak fleksibilitas di masa depan untuk mengubah jenis string yang kita kembalikan, tetapi sepertinya itu tidak akan terjadi.

Apakah reinterpret(String, ::Vector{UInt8} masuk akal sama sekali, atau ini pelesetan dari reinterpret ?

Itu sepertinya masuk akal.

Masalahnya adalah fungsi ini terkadang menyalin, jadi nama itu agak menyesatkan.

Benar, tetapi string seharusnya tidak berubah, jadi kita mungkin bisa lolos begitu saja.

Ada juga metode String(::IOBuffer) , tetapi sepertinya metode itu sudah tidak digunakan lagi menjadi readstring .

Saya telah memikirkan tentang perubahan API yang Anda usulkan juga, tetapi antarmuka string(a, b...) adalah ia merangkai dan menggabungkan argumennya, dan ini akan membuat pengecualian gotcha yang mengganggu untuk argumen pertama yang dapat dipanggil. Jika kita menghapus rangkaian dari string maka itu bisa dibuat untuk bekerja.

Ya, setuju; konsistensi dan menghindari gotcha adalah yang paling penting.

Mencatat masalah # 18326 dan # 3893 dalam kategori "argumen dimensi".

Jika saya dapat menangani item lain: memastikan perilaku kontainer yang bisa berubah-ubah didokumentasikan dan konsisten.

@ JaredCrean2 :

Saya tentu berharap itu tidak melibatkan pembuatan banyak "salinan defensif".

Misalnya, jika saya memiliki array tipe yang bisa berubah dan saya memanggil sort di atasnya, apakah titik array yang dikembalikan ke objek yang sama dengan array input, atau apakah itu menyalin objek dan membuat titik array yang dikembalikan ke mereka?

Objek yang sama. Saya cukup yakin semua metode penyortiran, getindex, pemfilteran, pencarian, dll koleksi kami mengikuti aturan ini, bukan?

Saya tidak berpikir ada kekurangan kejelasan atau konsistensi pada poin itu - selalu objek yang sama.

Sebenarnya, saya pikir satu - deepcopy mana intinya adalah Anda mendapatkan semua objek baru.

Apakah itu didokumentasikan di suatu tempat?

Tidak - kami bisa, tetapi saya tidak yakin di mana sebaiknya mendokumentasikannya. Mengapa fungsi membuat salinan tidak perlu? Dari mana Anda mendapat kesan bahwa mereka mungkin?

Halo. Saya belum melihat saya percaya ada komentar tentang serialisasi data.

Cepat atau lambat program julia akan ditulis dan dijalankan secara publik, data terkadang mulai bertingkat, selama bertahun-tahun. Serialisasi data misalnya. rantai: objek ke byte yang didorong oleh jenis (mungkin melalui json atau ...) harus dibangun agar tahan waktu. Berpikir tentang pembuatan versi semantik dan api web mungkin juga dihitung.

Bisakah kami mengharapkan serialisasi untuk data pengguna tetap dekat dengan https://github.com/JuliaLang/julia/blob/v0.5.1/base/serialize.jl ?

Mengapa fungsi membuat salinan tidak perlu? Dari mana Anda mendapat kesan bahwa mereka mungkin?

Saya tidak tahu apakah mereka melakukannya atau tidak. Sejauh yang saya tahu, perilaku itu tidak ditentukan. Dari komentar @JeffBezanson , ada orang yang menganjurkan membuat salinan defensif, yang dia lawan. Jadi dokumentasi harus menjawab pertanyaan tentang salinan defensif di suatu tempat.

Anda tampaknya menyiratkan semacam prinsip tindakan terkecil, tetapi bergantung pada detail algoritme, apa yang dimaksud dengan "tindakan terkecil" menjadi ambigu. Untuk mendapatkan konsistensi di seluruh API, saya rasa diperlukan panduan yang lebih spesifik.

@ o314 : ini adalah masalah tinjauan konsistensi API, saya tidak yakin bagaimana hubungan serialisasi.

@ JaredCrean2 : apakah objek tingkat atas disalin atau tidak tentu perlu didokumentasikan. Apa yang saya katakan adalah bahwa objek yang lebih dalam tidak pernah disalin, kecuali dengan deepcopy (jelas).

Apa yang saya katakan adalah bahwa objek yang lebih dalam tidak pernah disalin, kecuali dengan deepcopy (jelas).

Baru-baru ini ada diskusi tentang ini dalam konteks copy untuk beberapa pembungkus array, misalnya SubArray dan SparseMatrixCSC tetapi juga Symmetric , LowerTriangular . Menurut saya, di bawah kebijakan yang disebutkan di atas, copy akan menjadi noop untuk jenis pembungkus seperti itu. Apakah kebijakan yang Anda sebutkan merupakan tingkat abstraksi yang tepat di sini? Misalnya, saya pikir ini menyiratkan bahwa jika Array s diimplementasikan di Julia (membungkus buffer), perilaku copy pada Array s kemudian harus berubah menjadi noop.

Jika konvensi adalah bahwa objek yang lebih dalam tidak pernah disalin, maka yang tersisa hanyalah mendokumentasikannya. Dokumentasi adalah bagian yang sangat penting dari API. Perilaku ini mungkin tampak jelas bagi Anda (mungkin karena Anda menulis bagian-bagian kode), tetapi dari sudut pandang luar, perilaku ini tidak begitu jelas.

Edit: tidak melihat kiriman Andreas. Itu pertimbangan yang menarik.

@StefanKarpinski Saya setuju dengan maksud Anda.
Dan semua topik utama yang dibahas di sini sangat bagus dan cerdas.

Tetapi terkadang saya sedikit takut tentang keseimbangan antara proses dan data di Julia:

Kita bisa memanggil fortran atau c dengan mudah pasti,
Tetapi kode akan disebarkan dengan mudah di pusat data modern, misalnya. aws lambda dengan fungsinya sebagai pola layanan. akankah kode dapat dengan mudah dipanggil melalui internet, api terbuka?

Kadang-kadang seseorang harus menurunkan beban fungsional ke skala (tidak ada generik, tidak ada vaarg pada tanda tangan fungsi, tidak ada perintah tinggi pada api publik) dan mengikat lebih sistematis data di belakang (skema json / openapi).

Saya telah melihat beberapa perpustakaan python yang sangat bagus tenggelam dengan cara ini dan itu sangat disayangkan.

Saya pikir itu adalah poin penting bagi bahasa 1.0 untuk menjaga data dan fungsi tetap seimbang dan modular agar dapat dengan mudah diterapkan di web. Dan untuk fungsi antarmuka ini harus lebih sedikit hewan peliharaan dan lebih berorientasi pada ternak saat dibutuhkan.

Mungkin bukan itu intinya dalam topik ini.

@StefanKarpinski Saya mungkin telah salah paham tentang kiriman Anda. Saat kamu berkata

apakah objek tingkat atas disalin atau tidak tentu perlu didokumentasikan

apa artinya "objek tingkat atas"? Jika saya memiliki x::Vector{MyMutableType} , apakah objek tingkat atas x atau elemen x ?

Objek tingkat atas mengacu pada x itu sendiri, bukan elemen x .

@andreasnoack Gagasan tentang objek tingkat atas harus mengacu pada struktur abstrak yang diimplementasikan, bukan detail implementasi.

mungkin menambahkan float dan fungsi serupa lainnya yang berfungsi pada tipe vs nilai?

Melihat catatan rilis 0.6, tampaknya aneh bahwa iszero(A::Array{T}) diperkenalkan, sementara banyak fungsi lainnya (misalnya sumabs , isinteger , isnumber ) melalui array tidak lagi digunakan untuk mendukung all(f,A) .

Ada nol array, dan mereka adalah elemen nol dalam ruang vektornya. iszero secara umum menguji apakah sesuatu adalah invers aditif, yang mana nol array.

Kembali. konsistensi garis bawah dalam nama fungsi, berikut adalah catatan singkat untuk count_ones dan count_zeros .

Menurut saya, jika Anda ingin menjaga API Julia tetap konsisten, Anda perlu memiliki beberapa perangkat lunak yang memungkinkan Anda (a) menentukan aturan / konvensi API, (b) melakukan analisis statis kode Julia untuk mendeteksi penyimpangan dari aturan / konvensi tersebut, dan (c) menawarkan saran. Alat seperti itu akan menguntungkan Julia Base dan semua Paket Julia. Paket Julia baru dapat membantu. (Lidah di pipi: hal pertama yang harus dilakukan paket ini adalah menyarankan namanya sendiri; APICheck.jl, ApiCheck.jl, API_Check.jl, APIChecker.jl, JuliaAPIChecker.jl, dll.) Saya agak baru mengenal Julia, jadi tidak ingin memimpin dalam hal seperti itu. Namun, saya tidak keberatan berkontribusi. Ada saran tentang cara menjalankannya?

Kami akan senang memilikinya di Lint.jl!

num2hex dan hex2num (# 22031 dan # 22088)

Saya juga percaya bahwa Lint.jl adalah paket yang tepat untuk pemeriksaan konsistensi API Julia. Tetapi jika kita menempuh jalan itu, daftar asli Stefan harus dibuat lebih tepat. Misalnya ketika dia menulis "kita harus memastikan bahwa semua koleksi di DataStructures memiliki API yang konsisten", pertanyaan yang muncul di benaknya adalah:

  • Apa yang membuat struktur data menjadi kumpulan? (Daftar koleksi di dasar)
  • Apa saja fungsi yang HARUS didukung oleh sebuah koleksi? (Spreadsheet fungsi berdasarkan koleksi)
  • Apa yang seharusnya menjadi tanda tangan dari masing-masing fungsi tersebut?
  • Apakah API yang disediakan oleh Base untuk koleksi sebenarnya sudah konsisten?

Untuk mengelola inventaris dan analisis seperti itu, kita mungkin ingin menambahkan proyek ke repositori Julia (proyek # 8), atau ke repositori JuliaPraxis (disarankan offline oleh TotalVerb) atau ke repositori Lint. Dalam hal ini kita perlu memilah siapa yang akan memiliki proyek semacam itu, orang mana yang harus dilibatkan sejak awal, dan siapa yang harus membuat keputusan akhir tentang apa sebenarnya konvensi Julia (untuk tujuan linting).

Tetapi sebelum melangkah lebih jauh ke arah ini, saya ingin bertanya kepada

Saya setuju bahwa menjelaskan hal ini secara spesifik adalah ide yang bagus. Mencari tahu daftar apa yang seharusnya menjadi bagian dari pekerjaan di sini - jika Anda ingin menerobosnya, itu akan bagus.

Apakah kita benar-benar membutuhkan Base.datatype_module dan Base.function_module?

Sebuah fungsi "modul" terpadu (mungkin getmodule) yang dikirimkan pada tipe data dan fungsi tampaknya lebih konsisten bagi saya.

Bagaimana dengan garis bawah di @code_typed dan teman-teman?

Itu kesempatan bagus untuk refactoring (alasan yang dinyatakan untuk larangan garis bawah). Anda dapat memiliki makro @code dengan argumen pertama adalah jenis kode yang Anda inginkan.

( @bramtayl , harap ingat untuk meletakkan backtick di sekitar makro karena ini mem-ping "kode" pengguna github jika tidak; @code )

FWIW, penyelesaian tab hanya berfungsi dengan nama fungsi. Mampu melakukan @code_<TAB> itu bagus ....

Jika refactoring dianggap tetapi ditolak, maka ada atau tidaknya garis bawah masih diperdebatkan, karena satu-satunya poin dari larangan garis bawah adalah untuk mendorong refactoring. Faktanya, dalam hal ini, sepertinya garis bawah harus didorong untuk membuat bahasanya lebih jelas

Audit garis bawah.

kontra-proposal: kami masih mengaudit nama-nama ini, tetapi kami malah menambahkan lebih banyak garis bawah yang akan membuat kode lebih mudah dibaca (codetyped vs code_typed, isos2 vs is_os2).

Saya tidak absolut tentang ini. Saya pikir code_typed baik-baik saja, tab-complete yang berguna seperti yang ditunjukkan @KristofferC , dan sebenarnya tidak ada sesuatu yang jelas untuk dilewatkan sebagai argumen untuk memilih output mana yang Anda inginkan.

Bagi saya sepertinya kapal telah berlayar dengan menambahkan lebih banyak garis bawah, karena pada dasarnya kami harus menghilangkan setengah dari Base. Sebagai contoh, ada 74 fungsi predikat yang dimulai dengan is dan hanya 6 yang dimulai dengan is_ . Mana yang lebih masuk akal, mencela 6 atau 74?

Oke, ada beberapa tujuan yang saling bertentangan di sini:

1) Membuat nama lebih mudah dibaca
2) Mengurangi churn kode
3) Mendorong refactoring

Menghilangkan garis bawah dengan bertabrakan kata gagal di semua 3 front.

Metode show yang menerima aliran tidak ! -terminated tampaknya tidak sesuai dengan ketentuan biasa? Ref. https://github.com/JuliaLang/julia/pull/22604/commits/db9d70a279763ded5088016d9c3d4439a49e3fca#r125115063. Terbaik! (Edit: Saya kira ini cocok dengan metode write yang menerima aliran.)

Ada ketidakkonsistenan dengan API sifat. Beberapa sifat dihitung dengan menyebut sifat seperti
TypeArithmetic(Float64)
sementara yang lain fungsi ini harus dieja dengan huruf kecil:
iteratorsize(Vector{Float64})

Pertimbangkan untuk mengganti nama size -> shape (xref # 22665)

Array{T,1}() mungkin juga harus dihentikan:

julia> Array{Int,1}()                                                                                                                  
0-element Array{Int64,1}                                                                                                               

julia> Array{Int,2}()                                                                                                                  
WARNING: Matrix{T}() is deprecated, use Matrix{T}(0, 0) instead.                                                                       

Telah memikirkan tentang koleksi. Kami pada dasarnya memiliki tiga jenis:

  • Koleksi sederhana set-like (atau bag-like), yang hanya berisi beberapa nilai.
  • Koleksi mirip larik, yang menambahkan indeks di samping data.
  • Koleksi mirip Dict, yang memiliki indeks sebagai bagian dari datanya, yaitu k=>v pairs.

Saya menjadi skeptis dengan perilaku seperti dikt. Burung kenari di tambang batu bara adalah map , yang beroperasi pada pasangan nilai-kunci tidaklah alami, karena Anda biasanya tidak ingin mengubah kumpulan kunci. Ini juga memungkinkan untuk array dan dicts untuk mengimplementasikan antarmuka yang sama:

  • keys sesuai dengan eachindex
  • mapindexed dan filterindexed akan berguna untuk dicts dan array. Ini seperti peta dan filter kecuali juga meneruskan fungsi Anda indeks item yang dimaksud.
  • Array dan dicts (dan diberi nama tupel, dan mungkin yang lain) dapat menggunakan iterator pairs , yang pada dasarnya merupakan jalan pintas untuk zip(keys(c), values(c)) .

Pertimbangkan untuk mengganti nama ind2sub dan sub2ind , yang tampaknya matlabisme, dan yang memiliki nama non-julian dan aneh untuk pengguna non-matlab. Nama yang memungkinkan adalah indice dan linearindice . Saya tidak berani membuat PR karena saya tidak yakin apa yang orang pikirkan tentang itu, tapi akan lakukan jika ada dukungan.

Hal yang sama dengan rad2deg dan deg2rad .

Ref. # 22791 ( select -> partialsort ). Terbaik!

Satu hal yang belum saya lihat di sini: apakah argumen posisi opsional masuk pertama atau terakhir? Terkadang argumen posisi opsional ditempatkan lebih dulu, seperti dalam sum(f, itr) dan rand([rng,] ..) . Tapi di tempat lain mereka pergi terakhir, misalnya median(v[, region]) atau split(s::AbstractString[, chars]) . Terkadang mereka bisa pergi dulu atau terakhir, tapi tidak keduanya! (Misalnya, mean dapat mengambil fungsi terlebih dahulu atau dimensi terakhir, tetapi tidak keduanya.)

Semantik bahasa saat ini memaksa argumen opsional untuk menjadi yang terakhir: Anda dapat menulis f(a, b=1) tetapi tidak f(b=1, a) . Tetapi jika semua argumen opsional bertahan, apa yang terjadi pada blok do yang nyaman?

Jika tidak ada yang lain, itu adalah kutukan kecil bahwa bahasa harus mendefinisikan metode seperti itu, dari rand.jl : shuffle!(a::AbstractVector) = shuffle!(GLOBAL_RNG, a) . Sintaks argumen posisi opsional harus menangani kasus penggunaan ini dengan tepat.

Mungkin harus masuk ke masalah terpisah, tetapi tampaknya mungkin untuk memindahkan argumen opsional di mana pun Anda mau. Jadi misalnya, f(a = 1, b, c = 2) akan menentukan f(x) = f(1, x, 2) dan f(x, y) = f(x, y, 2)

xref # 22460 untuk upaya (tidak populer) dalam mengaktifkan argumen default di posisi mana pun.

Mungkin mengganti nama warn menjadi warning (matlab juga menggunakan ini), bukan masalah besar, tapi saya pikir saya akan menyebutkan?

Saya suka warn karena ini kata kerja, seperti throw .

Saya sangat bingung dengan ini:

julia> f(;a=1,b=1) = a+b                                                                                                                              
f (generic function with 1 method)                                                                                                                    

julia> f(a=4,5)            # I intended to write f(a=4,b=5)                                                                                                                           
ERROR: MethodError: no method matching f(::Int64; a=4)                                                                                                
Closest candidates are:
  f(; a, b) at REPL[13]:1

Saya sarankan hanya mengizinkan kata kunci terakhir saat memanggil fungsi, mirip dengan saat menentukan fungsi kata kunci.

Saya sarankan hanya mengizinkan kata kunci terakhir saat memanggil fungsi, mirip dengan saat menentukan fungsi kata kunci.

Ada banyak API yang memasukkan kata kunci di posisi lain berguna dan ergonomis.

Karena penasaran, apakah ada urutan evaluasi yang ditentukan untuk argumen posisi dan kata kunci? Saya melihat beberapa masalah lama dan https://docs.julialang.org/en/latest/manual/functions/#Evaluation -Scope-of-Default-Values-1 berbicara tentang cakupan, tetapi tidak ada yang saya temukan yang menyatakan apakah misalnya argumen dievaluasi dari kiri ke kanan, atau semua argumen posisi dievaluasi sebelum semua argumen kata kunci, atau jika tidak ada urutan evaluasi yang ditentukan (atau yang lainnya).

@yurivish , untuk kata kunci, lihat dokumen (juga https://github.com/JuliaLang/julia/issues/23926). Untuk yang opsional ceritanya sedikit lebih ribet, mungkin baca disini . (Perhatikan bahwa pertanyaan lebih baik ditanyakan di https://discourse.julialang.org/)

Tampaknya tidak sepadan dengan masalahnya sendiri, tetapi selalu tampak aneh bagi saya bahwa bits(1) mengembalikan String , sepertinya seharusnya BitVector atau Vector{Bool} .

Saya ingin menyarankan tinjauan tabel metode yang mengirimkan Function atau Callable . Mari kita coba memastikan API ini sesuai dengan yang kita inginkan… dan bahwa kita tidak melewatkan kesempatan untuk memungkinkan restrukturisasi tabel sedemikian rupa sehingga kita dapat mengizinkan objek apa pun.

Adapun all dan any , yang tampaknya langsung tidak berlaku lagi menjadi all(f(x) for x in xs) , yang sudah dikurangi eta menjadi all(Generator(f, xs)) dan seharusnya tidak ada overhead.

Tidak yakin apakah itu yang Anda maksud, tapi saya pikir itu layak menyatakan hanya dalam kasus: Saya hardcore terhadap mencela setiap fungsional-gaya API untuk generator. Kami memiliki any(f, x) dan all(f, x) dan banyak digunakan; -10000000 untuk menghapusnya (atau metode lainnya, sungguh).

Saya generator pro. Tampak seperti blok bangunan fundamental dari program lazy dan harus diekspor. all(Generator(f, xs)) terkadang lebih nyaman untuk fungsi yang ditentukan daripada all(f(x) for x in xs) . Juga +10000000 untuk mengembalikan saldo

Saya lebih suka memiliki lebih sedikit sintaks di sini jika memungkinkan. Jika mudah dan terbaca dan berhasil untuk mengekspresikan gagasan "ambil xs, terapkan f untuk semuanya, dan kembalikan benar jika semua itu benar", lalu mengapa kita harus memasukkannya ke dalam satu kata kerja?

Jika yang menjadi perhatian adalah kata benda yang tidak perlu x di f(x) for x in xs , maka saran @bramtayl untuk mengekspor Generator (mungkin menggunakan nama yang lebih baik seperti Map ?) masuk akal.

Hal-hal seperti all(isnull, x) cukup sederhana daripada all(isnull(v) for v in x) . Kami telah menghentikan fungsi allnull dari NullableArrays dan menggantikan all(isnull, x) ; jika sintaks itu hilang, kami mungkin harus memperkenalkannya kembali.

Bagaimana dengan mengganti nama strwidth menjadi stringwidth (Saya pikir ini adalah satu-satunya fungsi manipulasi string yang diekspor yang telah menyingkat string menjadi str)

Sebenarnya sudah diganti namanya menjadi textwidth (https://github.com/JuliaLang/julia/pull/23667).

IMO, masalah ini terlalu luas untuk memiliki pencapaian 1.0, mengingat kami ingin segera mendapatkan fitur yang dibekukan. Kami mungkin memerlukan banyak pemilik dan menetapkan serangkaian fungsi untuk ditinjau jika kami ingin melakukan ini.

Selain itu, ini adalah tempat lain di mana FemtoCleaner dapat memperbarui banyak hal secara otomatis dari postingan 1.0, meskipun akan menyenangkan jika semuanya baik-baik saja.

hanya komentar tentang lebar teks:

INFO: Testing Cairo
Test Summary:   | Pass  Total
Image Surface   |    7      7
Test Summary:   | Pass  Total
Conversions     |    4      4
Test Summary:   | Pass  Total
TexLexer        |    1      1
WARNING: both Compat and Cairo export "textwidth"; uses of it in module Main must be qualified
Samples        : Error During Test
  Got an exception of type LoadError outside of a <strong i="6">@test</strong>
  LoadError: UndefVarError: textwidth not defined
  Stacktrace:
   [1] include_from_node1(::String) at .\loading.jl:576
   [2] include(::String) at .\sysimg.jl:14
   [3] macro expansion at C:\Users\appveyor\.julia\v0.6\Cairo\test\runtests.jl:86 [inlined]
   [4] macro expansion at .\test.jl:860 [inlined]
   [5] anonymous at .\<missing>:?
   [6] include_from_node1(::String) at .\loading.jl:576
   [7] include(::String) at .\sysimg.jl:14
   [8] process_options(::Base.JLOptions) at .\client.jl:305
   [9] _start() at .\client.jl:371
  while loading C:\Users\appveyor\.julia\v0.6\Cairo\samples\sample_pango_text.jl, in expression starting on line 28

Pesan kesalahan tampaknya cukup jelas tentang apa masalahnya? Cairo perlu memperluas metode dasar.

help?>  Base.textwidth
  No documentation found.

  Binding Base.textwidth does not exist.

julia> versioninfo()
Julia Version 0.6.0
julia> Compat.textwidth
textwidth (generic function with 2 methods)

saya tidak ragu bahwa pesan (yang saya dapatkan melalui travis) tidak apa-apa, tetapi mengapa Compat mengekspor textwidth jika tidak dalam 0,6?

Karena itulah inti dari Compat? Diskusi ini terlalu banyak di luar ruang lingkup jadi saya sarankan kita bisa melanjutkannya pada wacana atau kendur.

Saya sarankan untuk mengubah copy menjadi shallowcopy dan deepcopy menjadi copy karena baru-baru ini saya perlu waktu cukup lama untuk menyadari bahwa salinan adalah salinan yang "dangkal" dan Fungsi yang saya tulis adalah memutasikan array array. Saya pikir akan jauh lebih intuitif jika copy akan melakukan salinan "dalam" dan sesuatu seperti shallowcopy digunakan untuk salinan dangkal? Saya tahu sekarang kapan harus menggunakan deepcopy , tetapi saya pikir banyak pengguna lain akan mengalami masalah yang sama.

Mari kita coba pertahankan masalah ini demi konsistensi API, bukan tas "khusus yang tidak saya sukai".

Associative nama tampaknya cukup konsisten dengan semua nama jenis lain di Julia.

Pertama, tipe biasanya bukan kata sifat. Kata benda adalah Association , dan digunakan setidaknya oleh beberapa dokumen Mathematica yang saya temukan.

Saya pikir AbstractDict akan jauh lebih konsisten dengan jenis lain seperti AbstractArray , AbstractRange , AbstractSet dan AbstractString , yang masing-masing memiliki jenis beton prototipe Dict , Array , Range , Set dan String .

Jenis pengecualian kami ada di semua tempat: beberapa diberi nama FooError , yang lain diberi nama BarException ; beberapa diekspor, sebagian besar tidak. Ini bisa menggunakan umpan untuk konsistensi.

Jadi apa yang lebih disukai, FooError atau BarException ? Diekspor atau tidak?

Bagi saya, BarException melibatkan suatu pola peningkatan / penangkapan.

Saya lebih suka banyak, dan beberapa lainnya di dunia fungsional juga, gunakan pola Some / None (*) di mana aliran kontrol lebih langsung dan dapat diprediksi.

Jadi +1 untuk FooError

(*) Some / Void ex Optional di Julia # 23642.

Apakah hal-hal ini masih di atas meja mengingat fitur pembekuan? Saya terutama ingin menangani argumen opsional vs. kata kunci, tetapi daftar fungsi dengan beberapa argumen opsional (kasus paling jelas untuk menggunakan argumen kata kunci sebagai gantinya) cukup panjang.

Silakan lihat! Saya belum mendapat kesempatan untuk membahas masalah ini secara sistematis.

BTW, saya telah mencatat ketidakkonsistenan dalam penamaan ciri: kita memiliki iteratorsize , iteratoreltype , tetapi IndexStyle , TypeRangeStep , TypeArithmetic dan TypeOrder . Sepertinya varian CamelCase lebih banyak dan lebih baru, jadi mungkin kita harus mengadopsi konvensi itu di mana-mana?

Itu pasti harus dibuat konsisten. Apakah Anda ingin membuat PR?

Saya pikir ini harus diperbaiki sebagai bagian dari https://github.com/JuliaLang/julia/pull/25356.

EDIT: lihat juga https://github.com/JuliaLang/julia/issues/25440

Ini sebagian besar dilakukan atau dapat dilakukan dalam rilis 1.x. Saya dapat memperbarui kotak centang, tetapi kami baru saja memeriksanya pada panggilan triase dan semuanya kecuali # 25395 dan audit garis bawah selesai.

Audit garis bawah

Berikut ini adalah analisis dari semua simbol yang diekspor dari Base yang berisi garis bawah, tidak digunakan lagi, dan bukan makro string. Hal utama yang perlu diperhatikan di sini adalah bahwa ini hanya nama yang diekspor; ini tidak termasuk nama yang tidak diekspor yang kami beri tahu orang-orang untuk menyebutnya memenuhi syarat.

Saya telah memisahkan hal-hal berdasarkan kategori. Semoga lebih bermanfaat daripada mengganggu.

Refleksi

Kami memiliki makro berikut dengan fungsi yang sesuai:

  • [] @code_llvm , code_llvm
  • [] @code_lowered , code_lowered
  • [] @code_native , code_native
  • [] @code_typed , code_typed
  • [] @code_warntype , code_warntype

Perubahan apa pun yang diterapkan ke makro, jika ada, harus diterapkan dengan cara yang sama ke fungsi.

  • [x] module_name -> nameof (# 25622)
  • [x] module_parent -> parentmodule (# 25629, lihat # 25436 untuk upaya sebelumnya dalam mengganti nama)
  • [x] method_exists -> hasmethod (# 25615)
  • [x] object_id -> objectid (# 25615)
  • [] pointer_from_objref

pointer_from_objref mungkin bisa dilakukan dengan nama yang lebih deskriptif, mungkin sesuatu seperti address ?

Alias ​​untuk interop C.

Jenis alias yang mengandung garis bawah adalah C_NULL , Cintmax_t , Cptrdiff_t , Csize_t , Cssize_t , Cuintmax_t , dan Cwchar_t . Yang diakhiri dengan _t harus tetap, karena mereka dinamai sesuai dengan tipe C yang sesuai.

C_NULL adalah yang aneh di sini, menjadi satu-satunya alias C yang berisi garis bawah yang tidak dicerminkan di C (karena di C ini hanya NULL ). Kami dapat mempertimbangkan untuk menyebut ini CNULL .

  • [] C_NULL

Sedikit menghitung

  • [] count_ones
  • [] count_zeros
  • [] trailing_ones
  • [] trailing_zeros
  • [] leading_ones
  • [] leading_zeros

Untuk diskusi tentang mengganti nama ini, lihat # 23531. Saya sangat menyukai menghapus garis bawah untuk ini, serta beberapa penggantian yang diusulkan dalam PR itu. Saya pikir itu harus dipertimbangkan kembali.

Operasi yang tidak aman

  • [] unsafe_copyto!
  • [] unsafe_load
  • [] unsafe_pointer_to_objref
  • [] unsafe_read
  • [] unsafe_store!
  • [] unsafe_string
  • [] unsafe_trunc
  • [] unsafe_wrap
  • [] unsafe_write

Mungkin tidak masalah untuk menyimpan ini sebagaimana adanya; keburukan garis bawah semakin menggarisbawahi ketidakamanan mereka.

Pengindeksan

  • [] broadcast_getindex
  • [] broadcast_setindex!
  • [] to_indices

Ternyata ada broadcast_getindex dan broadcast_setindex! . Saya tidak mengerti apa yang mereka lakukan. Mungkin mereka bisa menggunakan nama yang lebih deskriptif?

Menariknya, versi indeks tunggal to_indices , Base.to_index , tidak diekspor.

Jejak

  • [] catch_backtrace
  • [x] catch_stacktrace -> stacktrace(catch_backtrace()) (# 25615)

Agaknya ini adalah catch blok ekivalen backtrace dan stacktrace , masing-masing.

Tugas, proses, dan sinyal

  • [] current_task
  • [] task_local_storage
  • [] disable_sigint
  • [] reenable_sigint
  • [] process_exited
  • [] process_running

Aliran

  • [] redirect_stderr
  • [] redirect_stdin
  • [] redirect_stdout
  • [x] nb_available -> bytesavailable (# 25634)

Alangkah baiknya memiliki fungsi redirection IO -> IO lebih umum di mana semua ini dapat digabungkan, misalnya redirect(STDOUT, io) , sehingga menghapus garis bawah dan ekspor.

Promosi

  • [] promote_rule
  • [] promote_shape
  • [] promote_type

Lihat # 23999 untuk diskusi yang relevan tentang promote_rule .

Pencetakan

  • [x] print_with_color -> printstyled (lihat # 25522)
  • [] print_shortest (lihat # 25745)
  • [] escape_string (lihat # 25620)
  • [] unescape_string

escape_string dan unescape_string agak aneh karena mereka dapat mencetak ke aliran atau mengembalikan string. Lihat # 25620 untuk proposal untuk memindahkan / mengganti namanya.

Pemuatan kode

  • [] include_dependency
  • [] include_string

include_dependency . Apakah ini bahkan digunakan di luar Base? Saya tidak dapat memikirkan situasi di mana Anda menginginkan ini daripada include dalam skenario tipikal.

include_string . Bukankah ini hanya versi resmi dari eval(parse()) ?

Hal-hal yang tidak perlu saya kategorikan

  • [x] gc_enable -> GC.enable (# 25616)
  • [] get_zero_subnormals
  • [] set_zero_subnormals
  • [] time_ns

get_zero_subnormals dan set_zero_subnormals dapat dilakukan dengan nama yang lebih deskriptif. Apakah perlu diekspor?

+1 untuk method_exists => methodexists dan object_id => objectid . Ini juga agak konyol bahwa catch_stacktrace bahkan ada. Ini bisa tidak berlaku lagi pada definisinya, stacktrace(catch_backtrace()) .

Bagaimana perasaan kami tentang menghilangkan garis bawah C_NULL ? Saya sudah cukup terbiasa dengannya, tetapi saya juga membeli argumen bahwa tidak ada nama C* lainnya yang memiliki garis bawah.

Nama C lainnya adalah tipe, sedangkan C_NULL adalah konstanta. Saya pikir itu bagus bagaimana itu dan mengikuti pedoman penamaan.

dan mengikuti pedoman penamaan.

Bagaimana?

Konstanta sering kali berupa huruf besar semua dengan garis bawah - C_NULL mengikuti itu. Seperti yang dikatakan @ iamed2 , ini adalah nilai, bukan tipe, jadi konvensi penamaan Cfoo tidak selalu berlaku.

Saya keliru mengira https://github.com/JuliaLang/julia/blob/master/doc/src/manual/variables.md#stylistic -conventions mereferensikan konstanta tetapi ternyata tidak. Mungkin seharusnya begitu.

Saya menyarankan antarmuka yang konsisten, suara matematis, untuk ruang Hilbert umum di mana vektor bukan Julia Array. Nama fungsi seperti vecdot , vecnorm , dll. Bisa juga diganti dengan konsep umum inner dan norm seperti yang dibahas di https: // github. com / JuliaLang / julia / issues / 25565.

Seperti yang telah saya katakan beberapa kali, ini bukanlah masalah umum untuk hal-hal yang ingin diubah.

Saya yakin item yang tersisa di bawah payung ini untuk 1.0 adalah # 25501 dan # 25717.

Saya ingin melakukan sesuatu dengan (get|set)_zero_subnormals tetapi mungkin solusi jangka pendek terbaik adalah dengan melepasnya saja.

Sesuatu yang mungkin harus ditinjau adalah bagaimana angka diperlakukan dalam konteks operasi pengumpulan seperti map dan collect . Telah ditunjukkan bahwa yang pertama mengembalikan skalar tetapi yang terakhir mengembalikan larik 0D.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat