জুলিয়ায় প্রকারের ঘোষণার প্রয়োজন


16

জুলিয়াতে (উদাহরণস্বরূপ কোনও মডিউল বা প্যাকেজটির মধ্যে বলুন) স্পষ্টভাবে কোনও উপায়ের প্রয়োজন আছে যে ধরণেরগুলি অবশ্যই ঘোষণা করতে হবে ? যেমন উদাহরণস্বরূপ PackageCompilerবা Lint.jlএই জাতীয় চেকগুলির জন্য কোনও সমর্থন আছে? আরও বিস্তৃতভাবে, জুলিয়া স্ট্যান্ডার্ড বিতরণ নিজেই কোনও স্ট্যাটিক কোড বিশ্লেষক সরবরাহ করে বা সমতুল্য সরবরাহ করে যা এই প্রয়োজনীয়তাটি পরীক্ষা করতে সহায়তা করতে পারে?

একটি অনুপ্রেরণামূলক উদাহরণ হিসাবে, বলুন যে আমরা আমাদের বর্ধনশীল উত্পাদন কোড বেস কেবল সর্বদা প্রকার ঘোষিত কোড গ্রহণ করে তা নিশ্চিত করতে চাই , এই অনুমানের অধীনে ধরণের ঘোষণার সাথে বৃহত কোড বেসগুলি আরও রক্ষণাবেক্ষণের প্রবণতা রাখে।

যদি আমরা এই শর্তটি প্রয়োগ করতে চাই, তবে জুলিয়া কি তার প্রমিত বিতরণে প্রকার ঘোষণার প্রয়োজন হয় বা সেই লক্ষ্যে এগিয়ে যাওয়ার জন্য কোনও ব্যবস্থা দেয়? (যেমন: লিটারার, কমিট হুক বা সমমানের মাধ্যমে যা কিছু পরীক্ষা করা যায়?)


1
এটি কতটা সহায়তা করে তা নিশ্চিত নয়, তবে বোগুমিলের চিন্তাধারার মতো, কোনও জেনেরিক সংজ্ঞায়িত না করা থাকলে hasmethod(f, (Any,) )ফিরে আসবে false। আপনাকে এখনও আর্গুমেন্টের সংখ্যার সাথে মিল রাখতে হবে (অর্থাত্ hasmethod(f, (Any,Any) )একটি দ্বি-যুক্তি ফাংশনের জন্য)।
তাসোস পাপাস্টাইলিয়ানু

উত্তর:


9

সংক্ষিপ্ত উত্তরটি হ'ল: না, আপনার জুলিয়া কোডটি পরীক্ষা করার জন্য বর্তমানে কোনও সরঞ্জামাদি নেই। যদিও এটি নীতিগতভাবে সম্ভব, অতীতে এই দিকটিতে কিছু কাজ করা হয়েছিল তবে এখনই এটি করার ভাল উপায় নেই।

দীর্ঘ উত্তরটি হ'ল "টাইপ টীকাগুলি" এখানে একটি লাল হেরিং, আপনি যা চান তা টাইপ চেকিং, সুতরাং আপনার প্রশ্নের বিস্তৃত অংশটি আসলে সঠিক প্রশ্ন। টাইপ টীকাগুলি কেন একটি লাল হেরিং, সঠিক সমাধান নয় এমন আরও কিছু জিনিস এবং সঠিক ধরণের সমাধানটি কেমন হবে সে সম্পর্কে আমি কিছুটা কথা বলতে পারি।

প্রকারের টীকাগুলির প্রয়োজনীয়তা সম্ভবত আপনি যা চান তা সম্পাদন করে না: একটি যে ::Anyকোনও ক্ষেত্র, যুক্তি বা ভাব প্রকাশ করতে পারে এবং এতে একটি ধরণের টীকাযুক্ততা থাকতে পারে, তবে এমন একটি নয় যা আপনাকে বা সংকলকটিকে সেই জিনিসটির প্রকৃত প্রকার সম্পর্কে দরকারী কিছু বলে। এটি আসলে কোনও তথ্য না যুক্ত করে প্রচুর ভিজ্যুয়াল শব্দের যোগ করে।

কংক্রিট ধরণের টিকা প্রয়োজন কী? এটি কেবলমাত্র ::Anyসমস্ত কিছু (যা জুলিয়া ইঙ্গিতভাবে যাইহোকই করে তা কার্যকর করে দেওয়া) এটিকে বাতিল করে দেয়। তবে বিমূর্ত প্রকারের অনেকগুলি পুরোপুরি বৈধ ব্যবহার রয়েছে যা এটি অবৈধ করে তুলবে। উদাহরণস্বরূপ, identityফাংশনটির সংজ্ঞাটি হ'ল

identity(x) = x

আপনি xএই প্রয়োজনীয়তার অধীনে কোন কংক্রিট ধরণের টীকাযুক্ত রাখবেন ? সংজ্ঞাটি xযে কোনও প্রকারের ক্ষেত্রেই প্রযোজ্য type এটি ফাংশনের পয়েন্টের মতো। একমাত্র প্রকারের টীকা যা সঠিক x::Any। এটি কোনও অসঙ্গতি নয়: অনেকগুলি ফাংশন সংজ্ঞা রয়েছে যেগুলি সঠিক হওয়ার জন্য বিমূর্ত প্রকারের প্রয়োজন, সুতরাং কংক্রিট প্রকারগুলি ব্যবহার করতে বাধ্য করার ক্ষেত্রে কোনটি জুলিয়া কোড লিখতে পারে তার ক্ষেত্রে যথেষ্ট সীমাবদ্ধ থাকবে।

জুলিয়াতে প্রায়শই আলোচিত হয় "টাইপ স্থিতিশীলতা" এর একটি ধারণা। এই শব্দটি জুলিয়া সম্প্রদায়ের মধ্যে উদ্ভূত বলে মনে হয়েছে, তবে এটি আর এর মতো অন্যান্য গতিময় ভাষা সম্প্রদায় গ্রহণ করেছে, এটি সংজ্ঞায়িত করা কিছুটা জটিল তবে এর মোটামুটি অর্থ হল যে আপনি যদি কোনও পদ্ধতির আর্গুমেন্টের কংক্রিটের ধরনগুলি জানেন তবে, আপনি এর রিটার্ন মানটির প্রকারটিও জানেন। এমনকি যদি কোনও পদ্ধতি টাইপ স্থিতিশীল হয় তবে এটি গ্যারান্টি দেওয়ার পক্ষে যথেষ্ট নয় যে প্রকারের স্থিতিশীলতা কোনও ধরণের চেক হয় কিনা তা সিদ্ধান্ত নেওয়ার কোনও নিয়মের বিষয়ে কথা বলে না। তবে এটি সঠিক দিকে যাচ্ছে: আপনি প্রতিটি পদ্ধতির সংজ্ঞা টাইপ স্থিতিশীল তা পরীক্ষা করতে সক্ষম হতে চাই।

আপনি অনেকগুলি ধরণের স্থিতিশীলতার প্রয়োজন পড়তে চান না, এমনকি যদি আপনিও পারেন। জুলিয়া ০.০ থেকে ছোট ইউনিয়নগুলি ব্যবহার করা সাধারণ। এটি পুনরাবৃত্তি প্রোটোকলের পুনরায় নকশার সাথে শুরু হয়েছিল, যা এখন nothingইঙ্গিত দেয় যে পুনরাবৃত্তির (value, state)আরও মান রয়েছে যখন পুনরাবৃত্তি একটি টিউপল ফেরত বনাম সম্পন্ন হয় তা নির্দেশ করে । find*মান লাইব্রেরিতে ফাংশন এছাড়াও একটি ফিরতি মান ব্যবহার nothingকরে কোনো মূল্যই পাওয়া গেছে ইঙ্গিত। এগুলি প্রযুক্তিগতভাবে টাইপ অস্থিরতা, তবে তারা ইচ্ছাকৃত এবং সংস্থাপকটি অস্থিরতার আশপাশে তাদের সম্পর্কে অনুকূলিতকরণের বিষয়ে তর্ক করার পক্ষে যথেষ্ট ভাল। সুতরাং কমপক্ষে ছোট ইউনিয়নগুলি অবশ্যই কোডের মধ্যে অনুমোদিত হতে হবে। তদুপরি, লাইন আঁকার কোনও স্পষ্ট জায়গা নেই। যদিও সম্ভবত একটি বলতে পারে যে একটি রিটার্ন টাইপUnion{Nothing, T} গ্রহণযোগ্য, তবে এর চেয়ে অনাকাঙ্ক্ষিত কিছু নয়।

আপনি সম্ভবত যা চান তা চান তবে ধরণের টীকাগুলি বা ধরণের স্থিতিশীলতার চেয়ে, এমন একটি সরঞ্জাম থাকা উচিত যা আপনার কোডটি পদ্ধতি ত্রুটিগুলি ফেলতে পারে না বা সম্ভবত আরও ব্যাপকভাবে এটি কোনও ধরণের অপ্রত্যাশিত ত্রুটি ছুঁড়ে ফেলবে না তা পরীক্ষা করবে। সংকলক প্রায়শই প্রতিটি কল সাইটে কোন পদ্ধতিটি ডাকা হবে তা নির্ধারণ করতে পারে বা কমপক্ষে কয়েকটি পদ্ধতিতে সংকুচিত করে। এভাবেই এটি দ্রুত কোড উত্পন্ন করে — পূর্ণ গতিশীল প্রেরণা খুব ধীর (উদাহরণস্বরূপ সি ++ তে ভ্যাটবিলের তুলনায় অনেক ধীর)। অন্যদিকে, আপনি যদি ভুল কোড লিখে থাকেন তবে সংকলকটি একটি নিঃশর্ত ত্রুটি নির্গত করতে পারে: সংকলকটি জানে যে আপনি ভুল করেছেন কিন্তু রানটাইম পর্যন্ত আপনাকে জানায় না যেহেতু সেগুলি ভাষা শব্দার্থক। একটির প্রয়োজন হতে পারে যে সংকলক প্রতিটি কল সাইটে কোন পদ্ধতিগুলি কল করতে পারে তা নির্ধারণ করতে সক্ষম হতে পারে: এটি গ্যারান্টি দেয় যে কোডটি দ্রুত হবে এবং কোনও পদ্ধতিগত ত্রুটি নেই। জুলিয়ার জন্য এটি একটি ভাল ধরণের পরীক্ষার সরঞ্জামটি করা উচিত। এই ধরণের জিনিসটির একটি দুর্দান্ত ভিত্তি রয়েছে কারণ কোড তৈরির প্রক্রিয়াটির অংশ হিসাবে কম্পাইলার ইতিমধ্যে এই কাজটি বেশিরভাগ ক্ষেত্রে করে।


12

এটা একটি মজার প্রশ্ন। মূল প্রশ্নটি হ'ল প্রকার হিসাবে ঘোষিত হিসাবে আমরা কী সংজ্ঞায়িত করি । যদি আপনি বোঝাতে চান যে ::SomeTypeপ্রতিটি পদ্ধতির সংজ্ঞায় একটি বিবৃতি রয়েছে তবে জুলিয়াতে আপনার গতিশীল কোড তৈরির বিভিন্ন সম্ভাবনা রয়েছে বলে এটি করা কিছুটা জটিল। সম্ভবত এই অর্থে একটি সম্পূর্ণ সমাধান আছে তবে আমি এটি জানি না (আমি এটি শিখতে পছন্দ করব)।

আমার মনে যে জিনিসটি আসে তবে তা অপেক্ষাকৃত সহজ বলে মনে হয় কোনও মডিউলের মধ্যে সংজ্ঞায়িত কোনও পদ্ধতি Anyতার যুক্তি হিসাবে গ্রহণ করে কিনা তা পরীক্ষা করা । এটি অনুরূপ তবে আগের বিবৃতিটির সমতুল্য নয়:

julia> z1(x::Any) = 1
z1 (generic function with 1 method)

julia> z2(x) = 1
z2 (generic function with 1 method)

julia> methods(z1)
# 1 method for generic function "z1":
[1] z1(x) in Main at REPL[1]:1

julia> methods(z2)
# 1 method for generic function "z2":
[1] z2(x) in Main at REPL[2]:1

methodsউভয় ফাংশনের স্বাক্ষর xহিসাবে গ্রহণ হিসাবে ফাংশন জন্য একই চেহারা Any

এখন কোনও মডিউল / প্যাকেজের Anyকোনও পদ্ধতিতে এটি সংজ্ঞায়িত কোনও পদ্ধতির আর্গুমেন্ট হিসাবে গ্রহণ করে কিনা তা যাচাই করতে নীচের কোডটির মতো কিছু ব্যবহার করা যেতে পারে (আমি কেবল এটি লিখে রেখেছি বলে আমি এটির ব্যাপকভাবে পরীক্ষা করে দেখিনি, তবে এটি বেশিরভাগ ক্ষেত্রে মনে হয় সম্ভাব্য কেসগুলি কভার করুন):

function check_declared(m::Module, f::Function)
    for mf in methods(f).ms
        if mf.module == m
            if mf.sig isa UnionAll
                b = mf.sig.body
            else
                b = mf.sig
            end
            x = getfield(b, 3)
            for i in 2:length(x)
                if x[i] == Any
                    println(mf)
                    break
                end
            end
        end
    end
end

function check_declared(m::Module)
    for n in names(m)
        try
            f = m.eval(n)
            if f isa Function
                check_declared(m, f)
            end
        catch
            # modules sometimes return names that cannot be evaluated in their scope
        end
    end
end

এখন আপনি এটি Base.Iteratorsমডিউলে চালালে আপনি পাবেন:

julia> check_declared(Iterators)
cycle(xs) in Base.Iterators at iterators.jl:672
drop(xs, n::Integer) in Base.Iterators at iterators.jl:628
enumerate(iter) in Base.Iterators at iterators.jl:133
flatten(itr) in Base.Iterators at iterators.jl:869
repeated(x) in Base.Iterators at iterators.jl:694
repeated(x, n::Integer) in Base.Iterators at iterators.jl:714
rest(itr::Base.Iterators.Rest, state) in Base.Iterators at iterators.jl:465
rest(itr) in Base.Iterators at iterators.jl:466
rest(itr, state) in Base.Iterators at iterators.jl:464
take(xs, n::Integer) in Base.Iterators at iterators.jl:572

এবং যখন আপনি উদাহরণস্বরূপ DataStructures.jl প্যাকেজটি পরীক্ষা করুন:

julia> check_declared(DataStructures)
compare(c::DataStructures.LessThan, x, y) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps.jl:66
compare(c::DataStructures.GreaterThan, x, y) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps.jl:67
cons(h, t::LinkedList{T}) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\list.jl:13
dec!(ct::Accumulator, x, a::Number) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:86
dequeue!(pq::PriorityQueue, key) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\priorityqueue.jl:288
dequeue_pair!(pq::PriorityQueue, key) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\priorityqueue.jl:328
enqueue!(s::Queue, x) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\queue.jl:28
findkey(t::DataStructures.BalancedTree23, k) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\balanced_tree.jl:277
findkey(m::SortedDict, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_dict.jl:245
findkey(m::SortedSet, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_set.jl:91
heappush!(xs::AbstractArray, x) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\arrays_as_heaps.jl:71
heappush!(xs::AbstractArray, x, o::Base.Order.Ordering) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\arrays_as_heaps.jl:71
inc!(ct::Accumulator, x, a::Number) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:68
incdec!(ft::FenwickTree{T}, left::Integer, right::Integer, val) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\fenwick.jl:64
nil(T) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\list.jl:15
nlargest(acc::Accumulator, n) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:161
nsmallest(acc::Accumulator, n) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:175
reset!(ct::Accumulator{#s14,V} where #s14, x) where V in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:131
searchequalrange(m::SortedMultiDict, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_multi_dict.jl:226
searchsortedafter(m::Union{SortedDict, SortedMultiDict, SortedSet}, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\tokens2.jl:154
sizehint!(d::RobinDict, newsz) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\robin_dict.jl:231
update!(h::MutableBinaryHeap{T,Comp} where Comp, i::Int64, v) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\mutable_binary_heap.jl:250

আমি যা প্রস্তাব করি তা আপনার প্রশ্নের সম্পূর্ণ সমাধান নয় তবে আমি এটি নিজের জন্য দরকারী বলেই এটি ভাগ করে নেওয়ার কথা ভেবেছিলাম।

সম্পাদনা

উপরের কোডটি কেবলমাত্র fহিসাবে গ্রহণ করে Function। সাধারণভাবে আপনি কল করতে পারেন এমন ধরনের থাকতে পারে। তারপরে check_declared(m::Module, f::Function)স্বাক্ষরটি পরিবর্তিত হতে পারে check_declared(m::Module, f)(আসলে তখন ফাংশনটি নিজেই Anyদ্বিতীয় যুক্তি হিসাবে মঞ্জুরি দেয় :)) এবং সমস্ত মূল্যবান নাম এই ফাংশনে পাস করে pass তারপরে আপনাকে পরীক্ষা করতে হবে যে ফাংশনের অভ্যন্তরে methods(f)ইতিবাচক lengthআছে কি না ( methodsঅ-কলযোগ্যরা দৈর্ঘ্যের মানটি দেয় 0)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.