זה לא מספר השורות

15/02/2024

מתי פונקציה מפסיקה להיות פונקציה? נניח שיש לנו בעיה שבשביל לפתור אותה אנחנו צריכים להוציא ממחרוזת רשימה של כל הספרות שבה. אולי אנחנו לא יודעים עדיין ביטויים רגולאריים ורק התחלנו ללמוד פייתון וחושבים להשתמש בלולאה, ולכן נכתוב את הפונקציה:

def to_list_of_digits(s: str) -> list[int]:
    result = []
    for ch in s:
        if ch.isdigit():
            result.append(int(ch))
    return result

וזה עובד! אבל אז אנחנו מגלים שבעצם בפייתון יש מנגנון שנקרא List Comprehension ושאנחנו יכולים לכתוב את הפונקציה בצורה הרבה יותר קצרה:

def to_list_of_digits(s: str) -> list[int]:
    return [int(ch) for ch in s if ch.isdigit()]

עכשיו השאלה - האם נישאר עם הפונקציה? אולי עדיף לקחת את השורה האחת ופשוט לשים אותה במקום הקריאה? מי החליט שצריכה להיות כזאת פונקציה בכלל? ואולי אם הייתי מראש יודע על List Comprehension לא הייתי כותב את זה כפונקציה?

התשובה מורכבת אבל כדאי להשאיר בראש כמה נקודות-

  1. זה לא כמות השורות. מה שהופך פונקציה לרעיון טוב הוא שהפונקציה מספרת סיפור. היא עוזרת לנו לקרוא את הקוד. פונקציה נותנת שם לפעולה מסוימת. אם השם הזה היה הגיוני כשהיא היתה ארוכה יש סיכוי טוב שהוא עדיין הגיוני, גם כשהיא לוקחת שורה אחת.

  2. פונקציה מאפשרת נקודת בדיקה ומשהו לדון עליו. אני יכול להסתכל על הפונקציה שמושכת ספרות ממחרוזת ולבדוק אם היא עובדת על מחרוזות מסוימות שאני מכיר, או להתלבט מה היא צריכה לעשות במקרי קצה.

  3. שימוש חוזר בפונקציה מספק הזדמנות לשינוי קל יותר - אם מחר נצטרך להחליף בכל מקום במערכת את ההתנהגות, למשל כדי למשוך מספרים מלאים במקום ספרות, הפונקציה תאפשר לעשות את זה במהירות ותוך שינוי של מקום אחד. העתקת שורת הקוד ושכפולה בקוד, אפילו אם זה רק שורה, גורמת לשינוי להיות יותר מסובך.

התרחיש של פונקציות ארוכות מדי בקוד הוא הרבה יותר נפוץ מקוד עם פונקציות קצרות מדי. רוב הזמן הנטייה הטבעית שלנו היא לא לייצר פונקציות גם כשצריך אותן. לכן לא הייתי ממהר למחוק פונקציות, גם אם קיצרנו אותן לשורה או שתיים.