ෆංක්ෂන් (Function) යනු කුමක්ද?

ඔබේ කේතය පිළිවෙලට, කාර්යක්ෂමව සහ නැවත නැවතත් භාවිතා කළ හැකි ලෙස සකස් කරන programming මූලධර්මයක් පිළිබඳ ගැඹුරු විග්‍රහයක්.

අපි මීට පෙර ලිපි වලින් **විචල්යයන් (Variables)** මගින් දත්ත ගබඩා කරන්නත්, **ලූප් (Loops)** මගින් කේත නැවත නැවත ක්‍රියාත්මක කරන්නත් ඉගෙන ගත්තා. අද අපි කතා කරන්නේ ඒ දෙකම එකතු කරලා, අපේ program එක තවත් බලවත් කරන, සංවිධානාත්මක කරන ඉතා වැදගත් සංකල්පයක් වන **ෆංක්ෂන් (Functions)** ගැන.

හිතන්න ඔබ රසවත් පළතුරු බීම එකක් (Juice) හදන්න යනවා කියලා. ඒ සඳහා ඔබට Juicer එකක් තියෙනවා. ඔබ කරන්නේ:

  1. ආදානය (Input): කැමති පළතුරු කෑලි (කෙසෙල්, අඹ) Juicer එකට දානවා.
  2. ක්‍රියාවලිය (Process): Juicer එක on කරාම, ඒක ඇතුළේ තියෙන යන්ත්‍ර සූත්‍ර ක්‍රියාත්මක වෙලා පළතුරු ටික අඹරලා, යුෂ හදනවා.
  3. ප්‍රතිදානය (Output): ඔබට රසවත් පළතුරු බීම එකක් වීදුරුවට ලැබෙනවා.

ඔබට පළතුරු බීම එකක් ඕන වෙන හැම වෙලාවකම අලුතෙන් Juicer එකක් හදන්න අවශ්‍ය නැහැ. තියෙන එකට පළතුරු දැම්මම ඇති. Programming වලදී **Function** එකක් කියන්නෙත් හරියට මේ Juicer එක වගේ වැඩක් කරන දෙයක්. ඒක යම්කිසි නිශ්චිත කාර්යයක් කරන්න හදපු, නමක් දීපු, නැවත නැවතත් භාවිතා කළ හැකි කේත කොටසක්.

මේ ලිපියෙන් අපි Functions ගැන සියල්ල ඉගෙන ගනිමු:


ෆංක්ෂන් (Function) එකක් යනු සවිස්තරව කුමක්ද? ⚙️

නිල නිර්වචනයට අනුව, **ෆංක්ෂන් එකක් යනු, යම් නිශ්චිත කාර්යයක් ඉටු කිරීම සඳහා වූ, නමක් ලබා දුන්, ස්වයං-අන්තර්ගත කේත කොටසකි (a named, self-contained block of code designed to perform a specific task).**

අපේ Juicer උදාහරණයෙන්ම කොටස් ටික වෙන් කරලා බලමු:

මූලික අරමුණ: Functions වල මූලිකම අරමුණ තමයි විශාල program එකක්, කුඩා, කළමනාකරණය කළ හැකි, එක් එක් කාර්යයට අදාළ කොටස් වලට (modules) කැඩීම. මේකට **Modularity** කියනවා. ඒ වගේම, එකම කේතය තැන් තැන් වල නැවත නැවත ලිවීමෙන් වැළකීම (DRY - Don't Repeat Yourself principle).

Functions අපේ programming වලට අත්‍යවශ්‍ය ඇයි? 🧐

කුඩා scripts ලියනකොට functions වල අවශ්‍යතාවය නොදැනුනත්, ඔබ විශාල, සංකීර්ණ වැඩසටහන් ලියන්න පටන් ගත්තම functions නැතුවම බැරි වෙනවා. ඒකට හේතු කිහිපයක් තියෙනවා.

1. කේතය නැවත භාවිතා කිරීමේ හැකියාව (Code Reusability)

හිතන්න ඔබට program එකේ තැන් 5කදී user කෙනෙක්ව පිළිගන්න පණිවිඩයක් print කරන්න ඕන කියලා. Function එකක් නැතුව ඔබ ඒ print statement එක 5 පාරක් ලියන්න ඕන. පස්සේ ඒ පණිවිඩය වෙනස් කරන්න වුනොත්? තැන් 5ම වෙනස් කරන්න වෙනවා.

ඒත් function එකක් හැදුවොත්, ඔබට අවශ්‍ය වෙන්නේ ඒ function එක තැන් 5දීම call කරන එක විතරයි. පණිවිඩය වෙනස් කරන්න ඕන වුනොත්, function එක ඇතුළේ එක තැනක් වෙනස් කරාම ඇති.

Functions නොමැතිව:


print("--------------------")
print("Welcome, User!")
print("Have a great day.")
print("--------------------")

# ... some other code ...

print("--------------------")
print("Welcome, User!")
print("Have a great day.")
print("--------------------")
    

Functions සමඟ:


def show_welcome_message():
    print("--------------------")
    print("Welcome, User!")
    print("Have a great day.")
    print("--------------------")

show_welcome_message()  # Call 1
# ... some other code ...
show_welcome_message()  # Call 2
    

මේක තමයි **DRY (Don't Repeat Yourself)** මූලධර්මය.

2. කේතය සංවිධානය සහ කියවීමට පහසු වීම (Organization and Readability)

Functions මගින් විශාල program එකක් පොඩි පොඩි කොටස් වලට කඩන නිසා, කේතය තේරුම් ගන්න හරිම ලේසියි. හරියට විශාල පොතක් පරිච්ඡේද (chapters) වලට වෙන් කරනවා වගේ. ඔබට යම්කිසි කොටසක ගැටළුවක් ආවොත්, සම්පූර්ණ program එකම බලන්න අවශ්‍ය නැහැ, අදාළ function එක විතරක් බැලුවම ඇති. හොඳට නම් දාපු functions දැක්කම program එකෙන් මොකක්ද වෙන්නේ කියලා බැලූ බැල්මට තේරුම් ගන්න පුළුවන්.

3. සංකීර්ණත්වය සැඟවීම (Abstraction)

ඔබ Juicer එකක් පාවිච්චි කරනකොට, ඒක ඇතුළේ මෝටරය කැරකෙන විදිහ, තල ක්‍රියාත්මක වෙන විදිහ ගැන දැනගන්න අවශ්‍ය නැහැ. ඔබ දන්නේ පළතුරු දැම්මම, බීම එකක් එනවා කියන එක විතරයි. Functions වලත් වෙන්නේ ඒකමයි. Function එක ඇතුළේ තියෙන සංකීර්ණ logic එක අපිට සඟවන්න පුළුවන්. Function එක භාවිතා කරන කෙනාට අවශ්‍ය වෙන්නේ ඒකට දෙන්න ඕන inputs මොනවද, ඒකෙන් ලැබෙන output එක මොකක්ද කියන එක විතරයි. මේකට **Abstraction** කියනවා.


Function එකක් හදන්නේ (Define) සහ භාවිතා කරන්නේ (Call) කොහොමද? ✍️

Function එකක් එක්ක වැඩ කරනකොට ප්‍රධාන පියවර දෙකක් තියෙනවා:

  1. Function Definition (ෆංක්ෂන් එක නිර්වචනය කිරීම): Function එකේ නම, inputs සහ එයින් කළ යුතු කාර්යය කුමක්ද කියා කේතයෙන් ලියන එක. මේක හරියට Juicer එකේ blueprint එක හදනවා වගේ.
  2. Function Call (ෆංක්ෂන් එක ඇමතීම): ඒ හදාගත් function එක වැඩසටහනේ යම් තැනකදී ක්‍රියාත්මක කරවීම. මේක හරියට Juicer එකට පළතුරු දාලා on කරනවා වගේ.

Function Definition in Python

Python වලදී function එකක් define කරන්නේ `def` කියන keyword එක භාවිතා කරලා.


def function_name(parameter1, parameter2):
    # This is the function body, it must be indented
    # Code to perform a specific task goes here
    # ...
    return result # Optional
    

Function Call in Python

Function එකක් call කරන්නේ ඒකේ නම සහ වරහන් භාවිතා කරලා. Parameters තියෙනවා නම්, වරහන් ඇතුළේ ඒවට අදාළ අගයන් (values) ලබා දෙන්න ඕන. මේ අගයන්ට **arguments** කියනවා.


# Defining a simple function
def greet():
    print("Hello from a function!")

# Calling the function
greet() # Output: Hello from a function!
    
Parameters vs. Arguments:

Parameters සහ Arguments පිළිබඳ ගැඹුරු විග්‍රහයක් 📥

Functions වලට දත්ත යවන විවිධ ක්‍රම තියෙනවා.

1. Positional Arguments

මේක තමයි සාමාන්‍යම ක්‍රමය. ඔබ call කරනකොට දෙන arguments, function definition එකේ තියෙන parameters වලට අනුපිළිවෙලට (position) ලැබෙනවා.


def introduce(name, age):
    print(f"My name is {name} and I am {age} years old.")

introduce("Kamal", 25) # "Kamal" goes to name, 25 goes to age
# Output: My name is Kamal and I am 25 years old.
    

2. Keyword Arguments

මෙහිදී ඔබ argument එක ලබා දෙනකොට, ඒක අදාළ වෙන්නේ මොන parameter එකටද කියලා නමින්ම (`keyword=value`) කියනවා. මේ නිසා අනුපිළිවෙල වැදගත් වෙන්නේ නැහැ.


# Using the same 'introduce' function
introduce(age=30, name="Sunil") # Order is changed, but it works correctly
# Output: My name is Sunil and I am 30 years old.
    

3. Default Parameters

Function එක define කරනකොටම parameter එකකට default අගයක් දෙන්න පුළුවන්. Function එක call කරනකොට ඒ parameter එකට argument එකක් දුන්නේ නැත්නම්, default අගය auto-magically භාවිතා වෙනවා.


def greet_user(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet_user("Nimali") # Uses the default greeting
# Output: Hello, Nimali!

greet_user("Saman", "Good Morning") # Overrides the default greeting
# Output: Good Morning, Saman!
    

`return` ප්‍රකාශය: Functions වලින් ප්‍රතිඵල ලබාගැනීම 📤

සමහර functions යම්කිසි කාර්යයක් කරලා (print කරනවා වගේ) නිකන් ඉන්නවා. ඒත් ගොඩක් වෙලාවට අපිට function එකෙන් යම් ගණනය කිරීමක් කරලා, ඒකෙන් ලැබෙන පිළිතුර ආපහු program එකේ ප්‍රධාන කොටසට ගන්න ඕන වෙනවා. අන්න ඒකට තමයි `return` statement එක භාවිතා කරන්නේ.

A function that doesn't have a `return` statement implicitly returns a special value called `None`.

`return` නොමැති Function එකක් (Procedure):


def print_sum(a, b):
    result = a + b
    print(f"The sum is: {result}")

print_sum(10, 5) # This just prints "The sum is: 15"
# We cannot store the result in a variable
    

`return` සහිත Function එකක්:


def calculate_sum(a, b):
    result = a + b
    return result  # Sends the value of 'result' back

# Now we can call it and store the returned value
total = calculate_sum(10, 5)
print(f"The returned value is: {total}") # Output: The returned value is: 15
print(f"We can use it for other calculations, like: {total * 2}") # Output: 30
    

`return` statement එක හමුවූ සැනින් function එකේ ක්‍රියාකාරීත්වය නතර වී, අදාළ අගය ආපසු යවනවා. `return` එකට පසුව ලියන කිසිම කේතයක් ක්‍රියාත්මක වෙන්නේ නැහැ.


Functions සහ Variable Scope 🌐

අපි ලූප්ස් ගැන කතා කරද්දී Scope ගැන පොඩ්ඩක් ඉගෙන ගත්තා. Functions එක්ක Scope කියන එක හරිම වැදගත්.

Local Variables

Function එකක් **ඇතුළත** හදන විචල්යයන් **Local Variables** ලෙස හැඳින්වේ. මේවා පවතින්නේ සහ භාවිතා කළ හැක්කේ ඒ function එක **ඇතුළත පමණි**. Function එක ක්‍රියාත්මක වී අවසන් වූ පසු එම local variables මතකයෙන් ඉවත් වේ.


def my_function():
    message = "Hello from inside the function" # 'message' is a local variable
    print(message)

my_function()
# The line below will cause an ERROR because 'message' doesn't exist outside the function.
# print(message) 
# NameError: name 'message' is not defined
    

Global Variables

Function එකකින් **පිටත**, program එකේ ප්‍රධාන මට්ටමේ හදන විචල්යයන් **Global Variables** ලෙස හැඳින්වේ. මේවා program එකේ ඕනෑම තැනක සිට (functions ඇතුළේ සිට වුවද) කියවිය (read) හැක.


global_message = "I am a global variable" # This is a global variable

def another_function():
    # We can access (read) the global variable from inside
    print(global_message)

another_function() # Output: I am a global variable
print(global_message) # Output: I am a global variable
    

සැලකිය යුතුයි: Function එකක් ඇතුළේ සිට global variable එකක අගය වෙනස් කිරීමට උත්සාහ කිරීමේදී, ඔබ `global` keyword එක භාවිතා කළ යුතුය. නමුත් මෙය හොඳ programming පුරුද්දක් ලෙස නොසැලකේ, ምክንያቱም එය කේතය තේරුම් ගැනීමට සහ දෝෂ නිරාකරණයට (debug) අපහසු කරයි.


සාරාංශය (Conclusion) ✨

ෆංක්ෂන් (Functions) යනු නවීන programming වල අත්තිවාරමයි. ඒවා නොමැතිව විශාල, සංකීර්ණ මෘදුකාංග නිර්මාණය කිරීම සිතාගත නොහැකිය. ඔබ functions භාවිතා කිරීමට දක්ෂ වුණා කියන්නේ, ඔබ programming වල ආධුනික මට්ටමෙන් ඔබ්බට ගමන් කරනවා යන්නයි.

අපි ඉගෙන ගත් ප්‍රධාන කරුණු:

දැන් ඔබ දන්නවා program එකක් කුඩා, කළමනාකරණය කළ හැකි කොටස් වලට කඩන්නේ කොහොමද කියලා. මෙම ලිපියේ ඇති උදාහරණ ඔබම ක්‍රියාත්මක කර, විවිධ inputs සහ return values සමඟින් ඔබේම functions නිර්මාණය කර පුහුණු වන්න.

ඊළඟට මොකක්ද? ඔබ දැන් දත්ත ගබඩා කරන්න (Variables), කේත නැවත ක්‍රියාත්මක කරන්න (Loops), සහ කේත සංවිධානය කරන්න (Functions) දන්නවා. අපේ ඊළඟ පියවර තමයි මේ දත්ත ස්ථිරවම ගබඩා කර තබන ආකාරය ඉගෙන ගැනීම. අපේ ඊළඟ ලිපිය වන **"Database යනු කුමක්ද?"** කියවන්නට අපි ඔබට ආරාධනා කරනවා!