סגנונות תכנות כאמונה דתית

שוב מאמר דיי מחשביסטי.

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

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

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

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

בואו ניתן כמה דוגמאות:

Design patterns

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

שפות Rapid Development

יש שפות, כמו Ruby on rail, פייתון, Visual Basic ואחרות, שנועדו לכך שיעבור כמה שפחות זמן בין תחילת הפיתוח לבין מוצר עובד. השיטה לעשות את זה היא ע”י מתן קיצורי דרך לכל פעולה סטנדרטית, ועיצוב מאוד גבוה שהופך לקוד פונקציונלי.

למרבה הצער, בעוד שהשפות האלו מעולות לתכנון ראשוני ולהוצאת Demo, אני מאוד לא מאמין בהן כדרך לייצר מוצר בעל אורך חיים של יותר מאשר שנה (כלומר – שהפיתוח עליו לוקח יותר מאשר שנה). מוצר שאמור לחיות הרבה זמן בד”כ נוטה לייצר צרכים ייחודיים. הבעיה עם שפות rapid development (ואני יודע שעכשיו אני עומד לקבל מבול של “נאצות” בתגובות) היא שהן מייצרות מדרגה שקשה לעבור עליה. כל מה שמכוסה ע”י החלקים שאותן עושה השפה בקלות הוא קל מאוד, כל מה שלא מכוסה הוא קשה מאוד. כאשר מוצר בשפה שכזו חי לתקופה ארוכה, אחד משני דברים נוטה לקרות. או שהמוצר מוותר על דברים שבעיקרון היינו רוצים שיעשה כדי לשמור על הקוד שלו פשוט (וכתוצאה מכך – המוצר הזה נוטה להראות כמו כל תוכנה אחרת מהתחום שרק נוצרה), או שהמתכנת עובד הרבה יותר קשה מאשר אילו היה בוחר בשפה שהיא לא rapid deveopment מלכתכילה, וגם מקבל מוצר פחות יציב.

אשליית “הביצועים הם בסדר”

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

כתוצאה מהעובדה הזו, יש נטיה לחשוב שביצועים זה לא משהו חשוב. הרבה תוכנות היום כתובות בשפות שנותנות ביצועים פחות טובים (או פחות טובים במקרה הגרוע) מאשר שפות התיכנות שהיו נהוגות לפני 15 ו-20 שנה. ברוב המקרים זה בסדר. לפעמים זה לא.

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

המטרה הסופית יותר חשובה מאשר האמצעים

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

בברכה
שחר
מייסד עמותת “מתכנתים למען שימוש שפוי בטכנולוגיה”

מאת

שחר שמש

מייסד–שותף וחבר ועד בתנועה לזכויות דיגיטליות מייסד שותף בעמותת „המקור”. פעיל קוד פתוח. מפתח שפת התכנות Practical

13 תגובות בנושא “סגנונות תכנות כאמונה דתית”

  1. תוכל בבקשה לתת דוגמא למשהו שקשה לעשות עם שפות דינאמיות?
    אני מאד מאמין בתכנון כמו שיש בלייקס. לעשות את ליבת המנוע של התוכנה בשפה קשיחה (סי++, וכדו’), ולחשוף כמה שיותר מהפונקציונאלות של התוכנה לפייתון או שפה דומה, כך שיהיה לך קל לשנות את התוכנה, וגם לא תסתכן בsegfaults בכל פעם שאתה עושה שינוי מינורי.
    אבל אין לי אפילו שבריר מהנסיון שיש לך, ולא כ”כ הבנתי מהטקסט מתי ולמה הגישה של השפות הדינאמיות צריכה להכשל, אז הייתי שמח לשמוע דוגמא שתבהיר לי את העניין.

  2. מה שמפריע לי זה לא החלק של הדינאמיות (כלומר – זה שהן לא מתקמפלות מראש), אלא זה שמבנה התוכנית נוצר ע”י מישהו אחר. בפרט – תשתית ה-rapid development. למעשה, אתה מוותר על הזכות להחליט מה ה-design של התוכנה שלך. יש מקרים שזה מתאים, ויש שלא, אבל כל המקרים שבהם זה מתאים נכנסים לשבלונות, ועל זה דיברתי.

    המקרה של פייתון הוא טיפה אחר, אבל דומה.

    בכל מקרה, מה שאנשים נוטים לשכוח זה שלכל דבר יש עלות. אם יש דברים שאתה עושה ממש ממש ממש בקלות, יהיו מקומות אחרים שבהם תשלם על זה ביוקר. אין שפה שבה ממש ממש קל לעשות הכל, אבל יש אנשים שנוטים לשכוח את זה. בגלל זה, לפרוייקטים שצריכים לחיות הרבה זמן, אני מעדיף שפות של “חבל ארוך”, כמו C++‎, שבהן נשמרת לינאריות מסויימת לגבי מה קשה ומה קל. הדברים הקלים הרבה יותר קשים, אבל הדברים הקשים הרבה הרבה הרבה יותר קלים.

    שחר

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

  4. חייב להגיד — הכתבה השפויה הראשונה שאני רואה בזמן האחרון בנושא תכנות/שפות תכנות.

    לצערי, אני נתקל בזמן האחרון בהרבה קוד גרוע שכתוב, ב-C או ב- ++C או אופילו בשפות יותר “מהירות”.

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

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

  5. קודם סיפור וא”חכ מסקנות. בזמנו כתבתי משהו שקשור בניהול הדפסות (כ-50 מדפסות וכמה אלפי הדפסות ליום) ב-SH. התוכנה עבדה כמה חודשים בלי בעיות. כשהמחשב היה עמוס והיו הרבה הדפסות התוכנה עבדה לאט מדי. החלפתי חלק קריטי ב-AWK, והמהירות עלתה בערך פי 10. לאחר עוד כמה זמן כתבתי את הכל ב-C והמהירות גברה פי 15 (לעומת גרסת ה-AWK).

    המסקנות שלי:
    1. יש הבדל ביצועי בסדרי גודל בין שפות SCRIPT לשפות שמתקמפלות לשפות מכונה.
    2. הרבה פעמים מספיק לעשות אופטימיזציה רק לקטעים קריטיים.
    3. הרבה יותר קל ומהיר לכתוב תוכנית שעושה משהו שכבר נעשה בכלי אחר (בלי שינויי תכנון) מאשר לתכנן אותו מראשיתו.
    4. (נובע מ-3 ו-2) כן כדאי לכתוב ולדבג את התכנון בשפה מהירה (כלשהיא) ואפשר אח”כ, אם מגלים צורך אח”כ (אולי אפילו החלטה מראש) לכתוב מחדש בשפה פרוצדרולית.

  6. הממ,

    1. דבר ראשון, יש הבדלי ביצועים משמעותיים בין sh לבין perl ו-Python. הראשון זו שפה שלחלוטין מבוצעת interpreted, בעוד השניים האחרים מתקמפלים ברגע הריצה. אני לא חושב שזה הוגן להשוות ביצועים שלהם. אני גם לא אוהב את sh לדברים גדולים מידי, בגלל שהשפה באמת באמת לא בנויה לזה.

    2. זה מאוד נכון, אבל לא תמיד קל לשלב טכנולוגיות. כמובן ש-sh בנויה לשלב טכנולוגיות, אבל המחיר כבר ציינת.

    3. נכון, לפעמים. לפעמים הבדלי הגישה בין הכלים אומר שלא נכון להעביר את הצורה שבה אתה עושה את זה במקום א’ למקום ב’.

    בתוך הסביבה של הגיבויים שלנו יש תוכנה שהיא לא יותר מאשר shell script. בגלל שהיא צריכה לרוץ בחלונות, נאלצתי לכתוב אותה ב-C++‎. זה לא היה כיף. היה עדיף לכתוב אותה ב-shell.

    4. אני חייב להודות שאחרי כמה שנים של דיבאג בקרנל, אני בד”כ משתמש ב-debug printf, ועל כן אני מאוד אגנוסטי לשפה שבה אני מדבג.

    שחר

  7. אני אחזיר לך בצ’ארלס פטסולד, זה שכתב את ספרי התכנות לחלונות בהוצאת microsoft press.

    הכותרת היא Does visual studio rot the mind.

    האם יש לי התנגדות לג’אווה (אני לא באמת מכיר C#‎)? כן, אבל פחותה. אני חושב שזו שפה שפחות מכריחה אותך לתכנת בצורה מסויימת. כמובן שייתכן שתכניס לי את J2EE, שאותו אני לא מכיר, ואז אני אשנה את דעתי מהקצה אל הקצה.

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

    שחר

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

    take it or leave it. אני לא מסוגל להגן על הדעה הזו.

    שחר

  9. I wanted to say this on the previous post but haven’t got around to it:

    Instead of arguing about coding style, at the bottom line the point was about how long did it take you to find out that there is a problem and how long did it take to find the actual problem and fix it.

    I’d like to argue that from my little programming experience (tongue in cheek, for those who don’t know me), religiously maintaining unit tests would have saved your time and maintaining them will also keep your mind at better ease about making any further changes to the code in the future.

    That by itself is relatively independent from your particular coding style or language (though wrapping system calls in user-level class methods would have helped since it would mean that you test the only place from which these system calls can be invoked (and on top of that, you might probably make the code less platform dependent by encapsulating environment-specific API’s)).

    As for code optimization – you are right that, from observing other programmer’s code, many programmers do not appreciate the importance of writing “good” code in terms of optimization and using the right algorithm. On the other hand today’s compilers are very strong and I remember reading at least onbe interesting article which shows how trying to get smart with Java to speed up execution using techniques which stem from wrong assumptions about how the JVM runs actually gets in the way the code gets executed.

    In short – I’m with the school that believes in “optimize only when you need it”.

    In general – I agree with your argument that there is no “one size fits all”.

    Amos

סגור לתגובות.