Jet menggunakan sistem inferensi tipe Julia untuk mendeteksi potensi bug dan ketik ketidakstabilan.
Peringatan
Harap dicatat bahwa karena integrasi ketat Jet dengan kompiler Julia, hasil yang disajikan oleh Jet dapat bervariasi secara signifikan tergantung pada versi Julia yang Anda gunakan. Selain itu, implementasi modul Base dan perpustakaan standar yang dibundel dengan Julia juga dapat mempengaruhi hasilnya.
Selain itu, sistem plugin kompiler Julia masih tidak stabil dan antarmuka sering berubah, sehingga setiap versi jet kompatibel dengan hanya versi terbatas Julia. Julia Package Manager akan secara otomatis memilih dan menginstal jet versi terbaru yang kompatibel dengan versi Julia Anda. Namun, jika Anda menggunakan versi malam Julia, harap dicatat bahwa versi jet yang kompatibel mungkin belum dirilis, dan jet yang diinstal melalui Julia Package Manager mungkin tidak berfungsi dengan baik.
Lihat lebih banyak perintah, opsi, dan penjelasan dalam dokumentasi.
Jet adalah paket Julia standar. Jadi Anda bisa menginstalnya melalui paket paket bawaan Julia dan menggunakannya seperti paket lainnya:
julia> using Pkg; Pkg . add ( " JET " )
[ some output elided ]
julia> using JET@report_opt Ketik ketidakstabilan dapat dideteksi dalam panggilan fungsi menggunakan makro @report_opt , yang berfungsi mirip dengan makro @code_warntype . Perhatikan bahwa, karena Jet bergantung pada inferensi tipe Julia, jika rantai inferensi rusak karena pengiriman dinamis, maka semua panggilan fungsi hilir tidak akan diketahui oleh kompiler, dan karenanya Jet tidak dapat menganalisisnya.
julia> @report_opt foldl ( + , Any[]; init = 0 )
═════ 2 possible errors found ═════
┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(foldl), op::typeof(+), itr::Vector{Any}) @ Base ./reduce.jl:198
│┌ foldl(op::typeof(+), itr::Vector{Any}; kw::@Kwargs{init::Int64}) @ Base ./reduce.jl:198
││┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(mapfoldl), f::typeof(identity), op::typeof(+), itr::Vector{Any}) @ Base ./reduce.jl:175
│││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Any}; init::Int64) @ Base ./reduce.jl:175
││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(+), nt::Int64, itr::Vector{Any}) @ Base ./reduce.jl:44
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Int64, itr::Vector{Any}) @ Base ./reduce.jl:48
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Int64, itr::Vector{Any}) @ Base ./reduce.jl:58
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Int64, x::Any) @ Base ./reduce.jl:86
││││││││ runtime dispatch detected: +(acc::Int64, x::Any)::Any
│││││││└────────────────────
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Int64, itr::Vector{Any}) @ Base ./reduce.jl:62
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Any, x::Any) @ Base ./reduce.jl:86
││││││││ runtime dispatch detected: +(acc::Any, x::Any)::Any
│││││││└────────────────────@report_call Ini berfungsi paling baik pada jenis kode stabil, jadi gunakan @report_opt secara bebas sebelum menggunakan @report_call .
julia> @report_call foldl ( + , Char[])
═════ 2 possible errors found ═════
┌ foldl(op::typeof(+), itr::Vector{Char}) @ Base ./reduce.jl:198
│┌ foldl(op::typeof(+), itr::Vector{Char}; kw::@Kwargs{}) @ Base ./reduce.jl:198
││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Char}) @ Base ./reduce.jl:175
│││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Char}; init::Base._InitialValue) @ Base ./reduce.jl:175
││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(+), nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:44
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:48
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:62
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Char, x::Char) @ Base ./reduce.jl:86
││││││││ no matching method found `+(::Char, ::Char)`: (op::Base.BottomRF{typeof(+)}).rf::typeof(+)(acc::Char, x::Char)
│││││││└────────────────────
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:49
││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(+)}, itr::Vector{Char}) @ Base ./reduce.jl:383
│││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(+)}, itr::Vector{Char}, ::Base.HasEltype) @ Base ./reduce.jl:384
││││││││┌ reduce_empty(op::Base.BottomRF{typeof(+)}, ::Type{Char}) @ Base ./reduce.jl:360
│││││││││┌ reduce_empty(::typeof(+), ::Type{Char}) @ Base ./reduce.jl:343
││││││││││ no matching method found `zero(::Type{Char})`: zero(T::Type{Char})
│││││││││└────────────────────report_package Ini mencari semua definisi metode dan menganalisis panggilan fungsi berdasarkan tanda tangan mereka. Perhatikan bahwa ini kurang akurat daripada @report_call , karena jenis input yang sebenarnya tidak dapat diketahui untuk metode generik.
julia> using Pkg; Pkg . activate (; temp = true , io = devnull ); Pkg . add ( " AbstractTrees " ; io = devnull );
julia> Pkg . status ()
Status `/private/var/folders/xh/6zzly9vx71v05_y67nm_s9_c0000gn/T/jl_h07K2m/Project.toml`
[1520ce14] AbstractTrees v0.4.4
julia> report_package ( " AbstractTrees " )
[ some output elided ]
═════ 7 possible errors found ═════
┌ isroot(root::Any, x::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/base.jl:102
│ no matching method found `parent(::Any, ::Any)`: AbstractTrees.parent(root::Any, x::Any)
└────────────────────
┌ AbstractTrees.IndexNode(tree::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:117
│ no matching method found `rootindex(::Any)`: rootindex(tree::Any)
└────────────────────
┌ parent(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:127
│ no matching method found `parentindex(::Any, ::Any)`: pidx = parentindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ nextsibling(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:132
│ no matching method found `nextsiblingindex(::Any, ::Any)`: sidx = nextsiblingindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ prevsibling(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:137
│ no matching method found `prevsiblingindex(::Any, ::Any)`: sidx = prevsiblingindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ prevsibling(csr::AbstractTrees.IndexedCursor) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/cursors.jl:234
│ no matching method found `getindex(::Nothing, ::Int64)` (1/2 union split): (AbstractTrees.parent(csr::AbstractTrees.IndexedCursor)::Union{Nothing, AbstractTrees.IndexedCursor})[idx::Int64]
└────────────────────
┌ (::AbstractTrees.var"#17#18")(n::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/iteration.jl:323
│ no matching method found `parent(::Any, ::Any)`: AbstractTrees.parent(getfield(#self#::AbstractTrees.var"#17#18", :tree)::Any, n::Any)
└──────────────────── Jet mengeksplorasi fungsi yang Anda sebut langsung serta calle mereka yang bisa disimpulkan . Namun, jika argumen jenis untuk panggilan tidak dapat disimpulkan, Jet tidak menganalisis callee. Akibatnya, laporan No errors detected tidak menyiratkan bahwa seluruh basis kode Anda bebas dari kesalahan. Untuk meningkatkan kepercayaan diri pada hasil jet menggunakan @report_opt untuk memastikan kode Anda menyimpang.
Jet berintegrasi dengan SnoopCompile, dan Anda kadang -kadang dapat menggunakan SnoopCompile untuk mengumpulkan data untuk melakukan analisis yang lebih komprehensif. Keterbatasan SnoopCompile adalah bahwa itu hanya mengumpulkan data untuk panggilan yang belum pernah disimpulkan sebelumnya, jadi Anda harus melakukan jenis analisis ini dalam sesi baru.
Lihat dokumentasi jet-integrasi SnoopCompile untuk perincian lebih lanjut.
Proyek ini dimulai sebagai proyek tesis sarjana saya di Universitas Kyoto, yang diawasi oleh Prof. Takashi Sakuragawa. Kami sangat terinspirasi oleh Ruby/Typeprof, alat pemahaman/pemeriksaan tipe eksperimental untuk Ruby. Tesis lulusan tentang proyek ini diterbitkan di https://github.com/aviatesk/grad-thesis, tetapi saat ini, hanya tersedia dalam bahasa Jepang.