फं

फंक्शन में Julia

2 अभ्यास

फंक्शन के बारे में

Basics अवधारणा में फंक्शन बनाने के दो तरीके बताए गए थे।

सबसे सामान्य रूप यह है, जिसमें कोड कई लाइनों में लिखा जाता है:

function muladd(x, y, z)
    x * y + z
end

छोटी परिभाषाओं के लिए "असाइनमेंट" या "सिंगल-लाइन" रूप:

muladd(x, y, z) = x * y + z

तीसरे, और भी छोटे रूप में, किसी छोटे और एक ही बार काम आने वाले फंक्शन को बिना नाम के बनाया जा सकता है:

julia> map(x -> 2x, 1:3)
4-element Vector{Int64}:
 2
 4
 6

julia> map((x, y) -> x * y, 1:3, 4:6)
3-element Vector{Int64}:
  4
 10
 18

यहाँ x -> 2x एक "एनोनिमस फंक्शन" है। यह वही है जिसे कुछ और भाषाएँ "लैम्ब्डा फंक्शन" कहती हैं।

ध्यान दीजिए कि एक से अधिक आर्गुमेंट होने पर ब्रैकेट की ज़रूरत पड़ती है, जैसे (x, y) -> x * y में।

Julia के कोड में एनोनिमस फंक्शन आम हैं, खासकर तब जब इन्हें map() और filter() जैसे हायर-ऑर्डर फंक्शन के साथ इस्तेमाल किया जाए।

फंक्शन के आर्गुमेंट

अब तक सिलेबस में हमने सिर्फ ऐसे फंक्शन देखे हैं जिनमें आर्गुमेंट की संख्या तय होती है, और फंक्शन कॉल करते समय वे सभी सही क्रम में देने पड़ते हैं। यह सीमित और असुविधाजनक होता, इसलिए कुछ और विकल्प भी मौजूद हैं।

वैकल्पिक आर्गुमेंट

कई भाषाओं की तरह Julia में भी फंक्शन बनाते समय हर आर्गुमेंट के लिए डिफ़ॉल्ट वैल्यू दी जा सकती है।

फिर फंक्शन कॉल करते समय आप उस आर्गुमेंट की वैल्यू दे सकते हैं, या उसे छोड़कर डिफ़ॉल्ट वैल्यू पर भरोसा कर सकते हैं।

julia> f(x, y=10) = x * y
f (generic function with 2 methods)

julia> f(2, 3)
6

julia> f(2)
20

जिन आर्गुमेंट की डिफ़ॉल्ट वैल्यू नहीं दी गई है, वे सब उन आर्गुमेंट से पहले आने चाहिए जिनकी डिफ़ॉल्ट वैल्यू दी गई है। इसका मतलब है कि f(x=2, y) सही नहीं होगा।

कीवर्ड आर्गुमेंट

अब तक के सारे उदाहरणों में positional arguments इस्तेमाल हुए हैं, यानी फंक्शन कॉल में दी गई वैल्यू का क्रम फंक्शन की परिभाषा में लिखे आर्गुमेंट के क्रम से मेल खाना चाहिए।

कई भाषाओं की तरह Julia में keyword arguments भी होते हैं। फंक्शन कॉल करते समय आर्गुमेंट का नाम लिखना ज़रूरी होता है, लेकिन कई कीवर्ड आर्गुमेंट किसी भी क्रम में दिए जा सकते हैं।

Julia की एक खास बात यह है कि फंक्शन की परिभाषा में कीवर्ड आर्गुमेंट (अगर हों) से पहले एक सेमीकोलन ; लगाना पड़ता है, ताकि वे पोज़िशनल आर्गुमेंट से अलग हो जाएँ। फंक्शन कॉल में अंतिम पोज़िशनल आर्गुमेंट और पहले कीवर्ड आर्गुमेंट के बीच ; या , में से कोई भी इस्तेमाल किया जा सकता है।

julia> b(x; y) = x + y
b (generic function with 1 method)

julia> b(2, y=3)
5

# keyword is required when calling
julia> b(2, 3)
ERROR: MethodError: no method matching b(::Int64, ::Int64)
The function `b` exists, but no method is defined for this combination of argument types.

डिफ़ॉल्ट वैल्यू भी वैकल्पिक रूप से दे सकते हैं, ठीक वैसे ही जैसे पोज़िशनल आर्गुमेंट के लिए।

अक्सर फंक्शन कॉल में myarg=myarg जैसा सिंटैक्स लिखना पड़ता है, जब पैरामीटर के समान नाम वाले वेरिएबल की वैल्यू पहले ही निकाल ली गई हो। ऐसी स्थिति में छोटा रूप लिखने की अनुमति है:

julia> width = 4.0
4.0

julia> height = √ width
2.0

julia> area(; width, height) = width * height
area (generic function with 1 method)

# repetition
julia> area(; width=width, height=height)
8.0

# shorthand form
julia> area(; width, height)
8.0

स्प्लैट और स्लर्प

अगर आपके मन में यह सवाल आया हो, तो बता दें कि Julia के सिंटैक्स के इस उपयोगी हिस्से के यही आम नाम हैं। दोनों ... ऑपरेटर की ओर इशारा करते हैं।

स्प्लैट

स्प्लैटिंग फंक्शन कॉल करते समय इस्तेमाल होती है, ताकि किसी संग्रह को उन अलग-अलग वैल्यू में खोला जा सके जिनकी फंक्शन को ज़रूरत होती है।

इसे समझाने की तुलना में दिखाना आसान है:

julia> fxyz(x, y, z) = x * y * z
fxyz (generic function with 1 method)

julia> xyz = [2, 3, 4]
3-element Vector{Int64}:
 2
 3
 4

# Using the vector directly in a function call is invalid
julia> fxyz(xyz)
ERROR: MethodError: no method matching fxyz(::Vector{Int64})
The function `fxyz` exists, but no method is defined for this combination of argument types.

# splatting converts the vector to 3 numbers, used as positional arguments
julia> fxyz(xyz...)
24

कुछ "फंक्शन कॉल" सिंटैक्टिक शुगर के पीछे छिपी होती हैं, इसलिए स्प्लैटिंग कम स्पष्ट जगहों पर भी इस्तेमाल की जा सकती है।

उदाहरण के लिए, मल्टीपल असाइनमेंट अंदर से एक टपल कंस्ट्रक्टर फंक्शन इस्तेमाल करता है:

julia> first, rest... = [1, 2, 3, 4]
4-element Vector{Int64}:
 1
 2
 3
 4

julia> first
1

julia> rest
3-element Vector{Int64}:
 2
 3
 4

कीवर्ड आर्गुमेंट भी स्प्लैटिंग से दिए जा सकते हैं, आम तौर पर named tuple इस्तेमाल करके। Dict भी चलेगा, लेकिन उसमें की सिंबल होना ज़रूरी है (यहाँ स्ट्रिंग नहीं चलेगी)।

# function with 3 keyword arguments
julia> fabc(; a, b, c) = a + b + c
fabc (generic function with 1 method)

# named tuple
julia> abc_nt = (a=2, b=3, c=4)
(a = 2, b = 3, c = 4)

# there are no positional arguments, so need to use ; before kw argument
julia> fabc(;abc_nt...)
9

# Dict
julia> abc_dict = Dict(:a=>2, :b=>3, :c=>4)
Dict{Symbol, Int64} with 3 entries:
  :a => 2
  :b => 3
  :c => 4

julia> fabc(;abc_dict...)
9
स्लर्प

स्लर्पिंग फंक्शन की परिभाषा में इस्तेमाल होती है, ताकि कितनी भी संख्या में अलग-अलग वैल्यू को एक संग्रह में पैक किया जा सके।

julia> f_more(i, j, more...) = i + j + sum(more)
f_more (generic function with 1 method)

julia> f_more(1, 3, 5, 7, 9, 11)
36

स्लर्प किए गए आर्गुमेंट का नाम (यहाँ more) कोई खास मायने नहीं रखता। इस वेरिएबल का टाइप कंपाइलर तय करता है, लेकिन पोज़िशनल आर्गुमेंट के लिए यह आम तौर पर tuple या उसी जैसा कुछ होता है।

कीवर्ड आर्गुमेंट भी स्लर्प किए जा सकते हैं, जिससे एक Dict (या उसी जैसा कुछ) मिलता है।

julia> f_kwslurp(x, y; switches...) = :mult in keys(switches) ? x * y : x + y
f_kwslurp (generic function with 1 method)

julia> f_kwslurp(5, 6; mult=true)
30

julia> f_kwslurp(5, 6)
11

कॉल में कोई भी कीवर्ड आर्गुमेंट इस्तेमाल किए जा सकते हैं। यह तय करना फंक्शन की परिभाषा का काम है कि किन कीवर्ड पर ध्यान देना है और किन्हें छोड़ देना है।

GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।

फंक्शन सीखिए

अभ्यास लॉक है

फंक्शन पर अभ्यास करने के लिए 1 और अभ्यास अनलॉक कीजिए