הקתדרלה והבזאר
אריק סטיבן ריימונד
הקתדרלה והבזאר
לינוקס הינה מערכת הפעלה חתרנית. מי היה מאמין אפילו לפני חמש שנים (בשנת 1991)
שמערכת הפעלה ברמה עולמית תוכל להתלכד, כאילו במטה קסם, מתוך עבודה חלקית של
מספר אלפי מפתחים המפוזרים בכל רחבי העולם, ומחוברים רק על-ידי הקורים העדינים
של האינטרנט?
בודאי לא אני. בתחילת 1993, כשלינוקס חדרה למודעות שלי, כבר הייתי מעורב בפיתוח
של תוכנת יוניקס וקוד-פתוח במשך עשר שנים. הייתי אחד מהתורמים הראשונים לפרוייקט
GNU באמצע שנות ה1980-. שחררתי הרבה תוכנת קוד-פתוח אל הרשת, כשפיתחתי או שהשתתפתי
בפיתוח מספר תוכנות (nethack, מצבי ה-VC וה-GUD של Emacs וכן xlife ואחרים) שעדיין
בשימוש רחב היום. חשבתי שידעתי איך צריך לעשות זאת.
לינוקס הפריכה את רוב ידיעותיי. נהגתי להטיף את האמונה היוניקסית של כלים קטנים,
בנייה מהירה של אב-טיפוס, ותכנות אבולוציוני במשך שנים. אבל האמנתי שהייתה גם
מורכבות קריטית מסוימת, שמעליה היתה דרושה גישה יותר מרוכזת ומתוכננת מראש.
האמנתי שהתוכנה החשובה ביותר (מערכות הפעלה וכלים באמת גדולים כמו העורך המתוכנת
Emacs) צריכה להבנות כמו קתדרלות, מעוצבות בזהירות על ידי מכשפים יחידים, או
קבוצות קטנות של קוסמים העובדים בבידוד נפלא, באופן כזה שאף בטא לא תשוחרר לפני
זמנה.
סגנון הפיתוח של לינוס טורבלדס - שחרר מוקדם והרבה, האצל סמכויות ככל יכולתך,
היה פתוח עד כדי ערבוביה - באה כהפתעה. לא הייתה שם בניית קתדרלה שקטה ומלווה
ביראת-כבוד - לעומת זאת נדמה שקהילת הלינוקס דמתה לבזאר גדול וסואן של מטרות
וגישות שונות (שסומלו על-ידי אתרי ארכיון הלינוקס, שנתנו ל
כל אחד לשים
שם קבצים) שמתוכו מערכת קוהרנטית ויציבה הייתה יכולה כביכול לצאת רק על-ידי
שורה של ניסים.
העובדה שנראה שסגנון הבזאר הזה עובד, ועובד היטב, באה כהלם יחודי. כאשר מצאתי
את דרכי שם, עבדתי קשה לא רק בפרוייקטים פרטיים, אלא גם בלנסות להבין מדוע עולם
הלינוקס לא רק שלא התפוצץ בבלבול אלא גם נדמה שהלך מחיל לחיל במהירות שבוני קתדרלות
לא היו יכולים לחלום עליה.
באמצע 1996 חשבתי שאני מבין. המזל נתן לי דרך מושלמת לבחון את התאוריה שלי,
בצורה של פרוייקט קוד פתוח שיכולתי להריץ במודע בסגנון הבזאר. כך עשיתי - והוא
היה הצלחה משמעותית.
זהו הסיפור של הפרוייקט. אשתמש בו כדי להציע כמה דברי-חוכמה על פיתוח קוד-פתוח
יעיל. לא את כל הדברים האלה למדתי לראשונה בעולם הלינוקס, אבל נראה איך עולם
הלינוקס נותן להם יתרון. אם אני צודק, הם יעזרו להבין בדיוק מה בדיוק עושה את
קהיליית הלינוקס למעיין של תוכנה טובה - וייתכן שהם יעזרו לך להיות יותר פורה
בעצמך.
הדואר חייב להגיע ליעדו
מאז 1993, אני מנהל את הצד הטכני של ספק אינטרנט קטן עם גישה חופשית בשם Chester
County InterLink (או CCIL בקיצור) בווסט-צ'סטר, פנסילבניה. הייתי בין מקימי
CCIL וכתבתי את תוכנת ה-BBS מרובת-המשתמשים הייחודית שלנו - תוכל לבדוק אותה
על-ידי ביצוע telnet ל-
locke.ccil.org.
כיום היא תומכת בכמעט שלושת אלפים משתמשים על שלושים קוים. העבודה הרשתה לי גישה
של 24 שעות ביממה לרשת דרך קו 56K של CCIL - למעשה, העבודה דרשה זאת!
הייתי די רגיל לדואר אלקטרוני אינטרנטי מיידי. מצאתי את העובדה שהייתי צריך
לעשות telnet מידי פעם בפעם ל-locke כדי לבדוק את הדואר שלי מעצבנת. רציתי שהדואר
שלי יועבר ל-snark (המחשב שלי בבית) כך שיודיעו לי ברגע שהוא הגיע ואוכל לטפל
בן בעזרת כל הכלים המקומיים שלי.
פרוטוקול שליחת הדואר של האינטרנט, SMTP (Simple Mail Transfer Protocol), לא
היה מתאים, משום שהוא עובד הכי טוב כאשר מחשבים מחוברים כל הזמן, בעוד שהמחשב
הפרטי שלי אינו מקושר תמיד לאינטרנט, ואין לו כתובת IP קבועה. מה שהייתי צריך
היא תוכנית שתושיט יד מעל לקשר הטלפוני הלא-רציף שלי ותביא את הדואר שלי כדי
שיועבר מקומית. ידעתי שדברים כאלה היו קיימים, ושרובם השתמשו בפרוטוקול ישומים
פשוט בשם POP (Post Office Protocol). POP כיום נתמך בצורה נרחבת על ידי רוב
תוכניות לקוח הדואר האלקטרוני הנפוצות, אבל באותו הזמן, הוא לא היה בנוי בשרת
הדואר שהשתמשתי בו.
הייתי זקוק לתוכנית-לקוח של POP3. אז ניגשתי לאינטרנט ומצאתי אחת. בעצם מצאתי
שלוש או ארבע. השתמשתי באחת מהם לזמן קצר, אבל היה חסר בה מה שנראה כיכולת ברורה
- היכולת לטפל בכתובות על הדואר שהובא כך שתשובות יעבדו כמו שצריך.
הבעייה היתה כזאת: נניח שמישהו בשם "joe" על locke שלח לי דואר. אם שלפתי את
הדואר ל-snark ואז ניסיתי לענות לו, אז תוכנית הדואר שלי הייתה בעליזות מנסה
לשלוח אותו ל-"joe" על snark, שכמובן אינו קיים. עריכת כתובות התשובה כדי שיכילו
את <@ccil.org> הפכה במהירות להיות טירדה רצינית.
זה היה בברור משהו שהמחשב היה צריך לעשות בשבילי. אבל אף לא אחת מתוכניות-לקוח
הקיימות של POP ידעה איך! וזה מביא אותנו ללקח הראשון:
1. כל עבודה טובה על תוכנה מתחילה בכל שהיא ממלאת צורך אישי של
המפתח.
ייתכן שזה היה צריך להיות ברור (הפתגם ש"הצורך הוא אבי ההמצאה" מסתובב הרבה זמן)
אבל לעיתים קרובות מפתחי תוכנה מבזבזים את זמנם כשהם עובדים למחייתם על תוכנות
שהם לא צריכים ולא אוהבים. אבל לא בעולם הלינוקס - מה שעשוי להסביר מדוע האיכות
הממוצעת של תוכנה שמקורה בקהילת הלינוקס היא כה גבוהה.
אז, האם מייד נכנסתי לתזזית אנרגטית של לכתוב תוכנית-לקוח POP3 חדשה שתתחרה
עם הקיימות? בחיים, לא! הסתכלתי בזהירות על עזרי ה-POP שהיו ברשותי ושאלתי את
עצמי "מי הכי קרוב למה שאני רוצה?" משום ש:
2. מתכנתים טובים ידועים מה לכתוב. מתכנתים גדולים יודעים מה לשכתב
(ולעשות בו שימוש חוזר).
בעוד שאינני מתיימר להיות מתכנת גדול, אני מנסה לחקות אחד כזה. תכונה חשובה
של מתכנתים גדולים היא עצלנות בונה. הם יודעים שאתה מקבל ציון 100 לא עבור מאמץ
אלא על תוצאות, ושזה כמעט תמיד יותר קל להתחיל מפתרון טוב חלקי מאשר מכלום.
לינוס טורבלדס, לדוגמא,
בעצם לא ניסה לכתוב את לינוקס מאפס. במקום זאת, הוא התחיל על ידי שימוש מחדש
של קוד ורעיונות מ-Minix, מערכת-הפעלה זעירה דמויית-יוניקס לתואמי PC. בסופו
של דבר, כל הקוד של Minix נעלם או נכתב מחדש לחלוטין - אבל כשהוא היה שם, הוא
שימש נקודת מוצא לעולל שבסוף נעשה לינוקס.
באותה רוח, יצאתי לחפש כלי POP קיים שהיה כתוב יחסית טוב, שישמש בתור בסיס לפיתוח.
מסורת שיתוף-הקוד של עולם יוניקס הייתה תמיד ידידותית לשימוש חוזר בקוד (זאת
הסיבה שפרוייקט GNU בחר את יוניקס כבסיס לתוכנות שלו, על אף הסתייגויות רציניות
ממערכת-ההפעלה עצמה). עולם הלינוקס קידם מסורת זו כמעט לגבול הטכנולוגי שלה;
יש לו טרה-בייטים של קוד-מקור פתוח נגישים לכלל. אם תקדיש זמן לחפש את הקוד
הכמעט-מתאים של מישהו אחר סביר יותר שבעולם הלינוקס תקבל תוצאות טובות יותר
מאשר בכל מקום אחר.
וזה הצליח בשבילי. יחד עם אלה שמצאתי קודם לכן, החיפוש השני שלי הביא סך של
תשעה מועמדים: fetchpop, PopTart, get-mail, gwpop, pimp, pop-perl, popc, popmail
ו-upop. החלטתי להשתמש ב-"fetchpop" של סונג-הונג או (Seung-Hong Ho). שמתי את
תכונת כתיבת הכותר מחדש שלי שם, ועשיתי מספר שיפורים שונים אחרים שהמחבר קיבל
לגרסה 1.9 שלו.
כמה שבועות לאחר מכן, נתקלתי בקוד של "popclient" של קארל הריס (Carl Harris),
ומצאתי שהייתה לי בעייה. על-אף של-fetchpop היו כמה רעיונות טובים מקוריים בתוכו
(כמו המצב של ריצה ברקע), הוא היה יכול לטפל רק ב-POP3 והיה כתוב בצורה די חובבנית
(סונג-הונג היה באותו הזמן מתכנת פיקח אבל לא מנוסה, ושתי התכונות היו בולטות)
הקוד של קארל היה יותר טוב, די מקצועי ויציב, אבל לתוכנית שלו היו חסרות מספר
יכולות של חשובות ודי מסובכות למימוש של fetchpop (כולל אלה שכתבתי בעצמי)
להישאר או לעבור? אילו עברתי, הייתי זורק את מה שכתבתי כבר בתמורה לבסיס פיתוח
טוב יותר.
מניע פרקטי לעבור היה הנוכחות של תמיכה במספר פרוטוקולים. POP3 הינו הפרוטוקול
הכי נפוץ מבין פרוטוקולי-השרת של תיבת דואר, אבל לא היחיד. fetchpop ושאר המתחרים
לא טיפלו ב-POP2, RPOP או APOP, וכבר היו לי מחשבות מעורפלות של אולי להוסיך
תמיכה ב-IMAP, (Internet Message Access Protocol - פרוטוקול תיבת-הדואר הכי
חדש והכי חזק) רק בשביל הכיף.
אבל הייתה לי סיבה יותר תאורטית לחשוב שמעבר יהיה רעיון טוב באותה מידה, משהו
שלמדעתי הרבה לפני לינוקס.
3. "תכנן שתזרוק (גרסה) אחת; אתה תעשה זאת בכל מקרה". (פרד ברוקס
(Fred Brooks), The Mythical Man Month, פרק 11)
או, אם לנסח זאת אחרת, לעיתים קרובות אינך ממש מבין את הבעייה, עד אחרי הפעם
הראשונה שאתה מממש פתרון. בפעם שנייה, ייתכן שתדע מספיק כדי לעשות זאת כהלכה.
כך שאם אתה רוצה לעשות את זה נכון, תתכונן להתחיל מחדש
לפחות פעם אחת
[JB - FILL IN].
אם כך (אמרתי לעצמי) שהשינויים ל-"fetchpop" היו הניסויון הראשונה שלי. אז עברתי.
אחרי ששלחתי את הקבוצה הראשונה של טלאי "popclient" לקארל הריס ב25- ביוני,
1996, גיליתי שהוא בעצם איבד עניין ב-"popclient" זמן מה לפני כן. הקוד היה
מאט מאובק, עם באגים משניים הנמצאים בו. היו לי הרבה שינויים לעשות, ומייד הסכמנו
שהדבר ההגיוני בשבילי לעשות היה לקחת פיקוד על התוכנית.
בלי שהרגשתי בכך, הפרוייקט תפס תאוצה. כבר לא שקלתי להכניס טלאים משניים לתוכנית-לקוח
קיימת של פרוטוקול POP. לקחתי על עצמי לתחזק אחד שלם, והיו רעיונות שעלו בדעתי
שידעתי שבודאי יובילו לשינויים גדולים.
בתרבות תוכנה שמעודדת שיתוף-קוד, זו הייתה דרך טבעית לפרוייקט להתפתח. אני פעלתי
על פי העקרון הזה:
4. אם יש לך את הגישה הנכונה, בעיות מעניינות ימצאו אותך.
אבל הגישה של קארל האריס הייתה אפילו יותר חשובה. הוא הבין ש-
5. כאשר אתה מאבד עניין בתוכנית, חובתך האחרונה היא להעביר אותה
ליורש כשיר.
מבלי שאי-פעם היינו צריכים לדון בכך, קארל ואני ידענו שהייתה לנו מטרה משותפת
שיהייה לנו הפתרון הטוב ביותר שקיים. השאלה היחידה בשביל מי מאיתנו הייתה אם
אני אוכל להראות שאני מישהו שניתן לבטוח בו. אחרי שעשיתי את זה, הוא נהג בעדנה
ושילח את התוכנה. אני מקווה שאנהג באותה מידה כאשר תורי יגיע.
החשיבות של משתמשים
וכך ירשתי את "popclient". וחשוב לא פחות - ירשתי את בסיס המשתמשים שלה. זה נפלא
שיש משתמשים, לא רק בגלל שהם הראייה שאתה ממלא צורך, אלא גם שעשית משהו כמו
שצריך. עם טיפוח מתאים, הם יכולים להפוך לשותפים לפיתוח.
עוד חוזק של מסורת היוניקס, אחד שלינוקס מביאה לקיצוניות מבורכת, הוא שרבים מהשמתשמים
הם גם האקרים. היות שהקוד זמין הם יכולים להיות גם האקרים יעילים. זה יכול להיות
שימושי מאוד לקיצור זמן ניפוי השגיאות. עם מעט עידוד, המשתמשים יאבחנו תקלות,
יציעו תיקונים, ואפילו ישפרו את הקוד הרבה יותר מהר משאפשר לעשות ללא עזרה.
6. התייחסות למשתמשים כאל שותפים לפיתוח היא הדרך חסרת הטרדות שלך
לשיפור קוד וניפוי שגיאות יעיל מהירים.
קל להמעיט בכוחו של האפקט הזה. למעשה, כמעט כולנו בעולם הקוד הפתוח המעטנו בהערכתנו
כמה טוב הוא יתמודד עם גידול במספר משתמשים ונגד סיבוכיות המערכת, עד שלינוס
טורבלדס הראה לנו שלא כך הוא הדבר.
למעשה, אני חושב שהתרומה הנבונה והחשובה ביותר של לינוס היא לא הרכבתו של הגלעין
(kernel) של לינוקס אלא המצאתו של מודל הפיתוח שלה. פעם, כאשר הבעתי דעה זו בנוכחותו,
הוא חייך וחזר בשקט על משפע שנהג לומר לעיתים קרובות: "אני בעצם אדם מאוד עצלן
שאוהב לקבל קרדיט על דברים שלמעשה נעשו על-ידי אחרים." עצלן כשועל. או כפי שרוברט
היינלין כתב, כידוע, על אחת מדמויותיו, עצלן מדי כדי להיכשל.
במבט לאחור, תקדים לשיטות והצלחה של לינוקס ניתן לראות בפיתוח של ספריית הליספ
של GNU Emacs וארכיוני קוד הליספ. בניגוד לפיתוח בסגנון ה"קתדרלה" של ליבת ה-C
של Emacs ורוב כלי ה-GNU האחרים, ההתפתחות של מאגר קוד הליספ הייתה דינאמית ומונעת
על-ידי המשתמשים. רעיונות ואבות-טיפוס למצבים הרבה פעמים שוכתבו שלוש או ארבע
פעמים לפני לשהגיעו לצורה יציבה וסופית. שיתופי פעולה מצומדים באופן רופף אשר
התאפשרו באמצעות האינטרנט,
בסגנון של לינוקס, קרו לעיתים קרובות.
בהחלט, הפרוייקט היחיד הכי מצליח שלי טרם fetchmail היה כנראה מצב ה-Version
Control של Emacs - שיתוף-פעולה דמוי-לינוקס שנעשה באמצעות דואר אלקטרוני עם
שלושה אנשים אחרים, רק אחד מהם (ריצ'ארד סטאלמן, הכותב של Emacs ומייסד ה-Free
Software Foundation) פגשתי עד היום. היה זה ממשק ל-SCCS, RCS ויותר מאוחר CVS
מתוך Emacs שנתן פעולות ניהול גרסאות של "נגיעה אחת". הוא התפתח ממצב מזערי וגס
בשם sccs.el שמישהו אחר כתב. והפיתוח שלו הצליח מפני שבניגוד ל-Emacs עצמו, קוד
של Emacs Lisp היה יכול לעבור דורות של שחרור/בדיקה/שיפור מהר מאוד.
הסיפור של Emacs אינו יחודי. היו מוצרי תוכנה אחרים עם ארכיטקטורה בעלת שתי רמות
וקהילת משתמשים בעלת שתי שכבות, ששילבו ליבה שפותחה בשיטת הקתדרלה ותיבת-כלים
שפותחה בשיטת הבזאר. מוצר כזה הוא MATLAB, כלי מסחרי לעיבוד והצגת נתונים. משתמשים
של MATLAB ומוצרים אחריםבעלי מבנה דומה מדווחים פה אחד שההישגים, הריגוש והחידוש
מתרחשים ברובם בחלקו הפתוח של הכלי בו קהילה גדולה ומגוונת יכולה להתעסק עימו.
[FILL IN]
כמה עיניים צריך כדי להשתלט על מורכבות?
דבר אחד הוא להבחין בגדול שסגנון הבזאר מאיד במידה ניכרת את זמן ניפוי השגיאות
והתפתחות הקוד. דבר אחר הוא להבין בדיוק איך ומדוע הוא עושה זאת ברמת המיקרו
של ההתנהגות היום-יומית של המפתח והבודק. בחלק זה (שנכתב שלוש שנים לאחר הפצת
המסמך המקורי, תוך שימוש בראיות שונות של מפתחים שקראו אותו ובחנו מחדש את התנהגותם
שלהם) ניקח מבט מקרוב על מה שבאמת קורה שם. קוראים ללא רקע טכני יכולים לדלג
בביטחה לחלק הבא.
מפתח אחד להבנה הוא להבין מדוע בדיוק שהסוג של דיווח-באג שמשתמשים שלא מודעים
לקוד המקור שולחים נוטה לא להיות מאוד שימושי. משתמשים שלא מודעים לקוד המקור
נוטים לדווח אך ורק על סימטומים שטחיים; הם לוקחים את סביבתם כמובן מאליו, ולכן
הם: (א) מחסירים נתוני-רקע הכרחיים (ב) לעיתים רחוקות כללים מרשם אמין לשחזור
הבאג.
הבעיה היסודית כאן היא חוסר התאמה בין המודלים המנטאליים של התוכנית, של המפתח
ושל הבוחן; הבוחן, מבחוץ מסתכל פנימה, והמפתח מבפנים מביט החוצה. בפיתוח קוד
סגור שניהם תקועים בפתקידים אלה ונוטים לדבר מחוץ לתחום הבנתו של השני ולמצוא
אחד את השני מאוד מתסכל.
פיתוח קוד-פתוח שובר את הקשר הזה, ועושה זאת הרבה יותר פשוט הן לבוחן והן למפתח
לפתח ייצוג משותף שמונחל בקוד-המקור הממשי ולתרשק ביעילות לגביו. מעשית, ישנו
שוני כביר הנותן יתרון למפתח בין סוג דיווח באגים שמדווח על סימפטומים חיצוניים
לבין הסוג שמתחבר ישירות לייצוג המנטלי של התוכנית מבוסס קוד-המקור שיש למפתח.
רוב הבאגים, רוב הזמן, נפתרים בקלות אם נתון תאור של תנאי השגיאה ברמת
קוד-המקור, אפילו יהיה לוקה-בחסר אבל מרמז. כאשר מישהו מבין בוחני התוכנה שלך
יכול לומר: "ישנה בעיית קצה בשורה nnn" או אפילו רק "תחת תנאים X, Y ו-Z המשתנה
הזה מתהפך" - אזי מבט חטוף על הקוד הבעייתי לעיתים קרובות מספיק לזהות את מהצב
המדוייק של התקלה ולייצר תיקון.
לכן מודעות לקוד המקור משני הצדדים מגבירה במידה רבה גם תקשורת טובה בין הצדדים
וגם העצמה בין מה שבוחן-בטא מדווח ומה שמפתח או מפתחי הליבה יודעים. בתורו,
משמע שזמן מפתחי הליבה נוטה להיות מנוצל היטב, אפילו עם משתפי פעולה רבים.
מאפיין אחר של שיטת הקוד הפתוח שמשמר את זמן המפתח הוא מבנה התקשורת של פרוייקטי
קוד פתוח אופייניים. מעל השתנשתי במונח "מפתח ליבה"; מונח זה משקף אבחנה בין
ליבת הפרוייקט (בדרך-כלל די קטנה; זה די מצוי למצוא מפתח ליבה יחיד, וטיפוסי
שיהיו אחד עד שלושה כאלה) לבין הילת הפרוייקט של בוחני-התוכנה ותורמים זמינים
(שלעיתים קרובות נספרים במאות).
הבעייה היסודית שארגון פיתוח-התוכנה המסורתי בא לפתור היא חוק ברוק (Brook's
Law): "הוספת יותר מתכנתים לפרוייקט שנמצא באיחור גורמת לו לאחר יותר". באופן
כללי יותר חוק ברוק מנבא שהמורכבות ועלויות התקשורת של פרוייקט עולים עם ריבוע
מספר המפתחים, בעוד שהעבודה שנעשית צומחת רק באופן לינארי.
מתי ורד אינו ורד?
אחרי שחקרתי את התנהגותו של לינוס ויצרתי תאוריה על הסיבה שהיא הייתה מוצלחת,
עשיתי החלטה מודעת לבחון תאוריה זו על הפרוייקט (שאני מודה שהוא הרבה פחות מסובך
ויומרני) החדש שלי.
אולם הדבר הראשון שעשיתי היה לארגן מחדש ולפשט את popclient הרבה. המימוש של
קארל האריס היה מאוד טוב, אבל אופיין בסוג של מסובכות לא הכרחית הנפוצה אצל
מתכנתי C רבים. הוא התייחס לקוד כאל מרכזי ולמבני הנתונים כאל תומכים בקוד.
כתוצאה מכך, הקוד היה יפהפה אבל תכנון מבני הנתוניתם היה אד-הוק ודי מכוער (לפחות
לפי הסטנדרטים הגבוהים של מתכנת LISP מנוסה שכמותי).
ברם, הייתה עוד מטרה לשכתוב חוץ מלשפר את הקוד ואת תכנון מבני הנתונים. היא
הייתה לפתח אותו למשהו שהבנתי לחלוטין. זה לא כיף להיות אחראי לתיקון שגיאות
בתוכנית שאי אפשר להבין.
במשך החודש הראשון או פרק זמן דומה, אם-כן, פשוט מילאתי את מה שהיה פועל יוצא
מהתכנון הבסיסי של קארל. השינוי הרציני הראשון שעשיתי היה להוסיף תמיכה ב-IMAP.
עשיתי זאת בכל שארגנתי מחדש את מכונות הפרוטוקולים אל מנוע כללי ושלוש טבלאות
של שגרות (עבור POP2, POP3 ו-IMAP). שינוי זה והשינויים הקודמים מדגימים עקרון
כללי שטוב למתכנתים לזכור, בייחוד בשפות כמו C שאין בהן מערכת טיפוסים דינאמית
באופן טבעי:
9. מבני נתונים חכמים וקוד מטופש עובדים הרבה יותר טוב מהכיוון
ההפוןך.
ברוקס, פרק 9: "הראה לי את תרשים הזרימה שלך ותסתיר את הטבלאות, ואני אמשיך
להיות מבולבל. הראה לי את הטבלאות - ובדרך כלל לא אזדקק לתרשים הזרימה שלך;
הוא יהיה ברור." אם ניקח בחשבון שלושים שנים של מעבר טרמינולוגי ותרבותי, זאת
אותה נקודה.
בנקודה זו (תחילת ספטמבר 1996, כשישה שבועות מהתחלת הסיפור) התחלתי לחשוב ששינוי
שם עשוי להיות במקום - ככלות הכל, זה כבר לא היה לקוח של POP יותר. אבל היססתי,
משום שעדיין לא היה דבר חדש באמת בתכנון. הגרסה שלי של popclient עדיין הייתה
צריכה לפתח ישות משלה.
זה השתנה, באופן יסודי, כאשר popclient למדה איך להפנות דואר שהובא ל-port של
SMTP. אני תכף אגיע לזה. אבל קודם לכן: אמרתי מקודם שהחלטתי להשתמש בפרוייקט
כדי לבחון את התאוריה שלי על מה שלינוס טורבלדס עשה נכון. איך (אפשר לשאול) עשיתי
זאת? בדרכים האלה:
- שחררתי מוקדם והרבה (כמעט אף-לא-פעם פחות מכל עשרה ימים; בתקופות של פיתוח
אינטנסיבי - פעם ביום)
- הגדלתי את רשימת בודקי הבטא שלי על ידי הוספת כל מי שפנה אלי בקשר ל-fetchmail.
- שלחתי הודעות מזמינות שיחה לרשימת בודקי הבטא בכל פעם ששחררתי גרסה, ובכך
עודדתי אנשים להשתתף.
- והאזנתי לבודקי-הבטא שלי, בכך שביקשתי את דעתם על החלטות תכנון והחמאתי
להם בכל פעם שהם שלחו טלאים ומשוב.
התשלום מאמצעים פשוטים אלה היה מיידי. מהתחלת הפרוייקט, קיבלתי דו"חות על באגים
מאיכות שמרבית המפתחים היו הורגים בשבילה, הרבה פעמים מלווים בתיקונים טובים.
קיבלתי ביקורת מחושבת, קיבלתי דואר של מעריצים, וקיבלתי הצעות חכמות ליכולות
חדשות. מה שמוביל ל:
10. אם תתייחס לבודקי-הבטא שלך כאילו הם המשאב היקר ביותר שלך, הם
ישיבו בכך שיהפכו למשאב היקר ביותר שלך.
מידה אחת מעניינת של ההצלחה של fetchmail היא הגודל של רשימת בודקי-הבטא, fetchmail-friends,
עצמו. בזמן שבו מאמר זה נערך לאחרונה (נובמבר 2000) היו לה 287 חברים ונוספים
לה שניים או שלושה מידי שבוע.
בעצם, כאשר ערכתי את המסמך בימים האחרונים של מאי 1997, מצאתי שהרשימה התחילה
לאבד חברים מהשיא של קרוב ל300- מסיבה מעניינת. מספר אנשים ביקשו ממני להוציא
אותם מהרשימה משום ש-fetchmail עובד כל כך טוב בשבילם שהם כבר לא צריכים לראות
את התנועה ברשימה! ייתכן שזה חלק ממחזור החיים הרגיל של פרוייקט בסגנון בזאר
בוגר.
Fetchmail מתבגר
הנה הייתי עם תכנון יפה וחדשני, קוד שידעתי שעובד טוב בגלל שהשתמשתי בו כל יום,
ורשימת בודקי-בטא הגדלה בהתמדה. בהדרגה הגעתי למסקנה שכבר לא התעסקתי בפרוייקט
טריביאלי ופרטי שעשוי במקרה להיות שימושי לכמה אנשים אחרים. הייתה בידי תוכנית
שכל האקר עם מערכת יוניקס וקשר דואר של SLIP/PPP באמת צריך.
יחד עם יכולת ההפנייה באמצעות SMTP, היא עקפה את התחרות מספיק רחוק כך שהיא
באופן פוטנציאלי תהיה "קוטלת הקטגוריה", אחת מאותן התוכניות הקלאסיות שממלאת
את הנישה שלה בכזאת יכולת שלא רק זורקים את החלופות הצידה אלא גם כמעט
שוכחים מהן.
אני חושב שאי אפשר לכוון או לתכנן להגיע לתוצאה כזאת. יש להגרר לתוכה על-ידי
רעיונות תכנון כה חזקים שאחריהם התוצאות נראות כבלתי-נמנעות, טבעיות, אפילו ייעודיות.
הדרך היחידה למצוא רעיונות כאלה היא להעלות הרבה רעיונות - או שיהיה השיפוט
ההנדסי לקחת רעיונות טובים של אנשים אחרים מעבר למה שאלה שהעלו אותם חשבו שאפשר
ללכת איתם.
לאנדי טננבאום היה הרעיון המקורי לבנות יוניקס פשוט שרץ על מחשבי IBM PC, לשימוש
ככלי הוראה (הוא קרא לו Minix). לינוס טורבלדס דחף את רעיון המיניקס רחוק יותר
ממה שאנדרו חשב קרוב לודאי שהוא יכול ללכת - והצמיח אותו למשהו נפלא. באותה דרך
(אם כי בקנה מידה קטן יותר), לקחתי מספר רעיונות של קארל האריס והארי הוצ'הייסר
ודחפתי אותם חזק. איש מאיתנו לא היה "מקורי" בדרך הרומנטית שאנשים חושבים שמהווה
גאונות. אולם מאידך, רוב המדע וההנדסה ופיתוח התוכנה אינם נעשים על גאונים מקוריים,
בניגוד למיתוסים של ההאקרים.
אחת היא, התוצאות עשו רושם - למעשה, זוהי סוג ההצלחה שכל האקר חי בשבילה! והמשמעות
שלהם הייתה שאצטרך להציב את הסטנדרטים שלי אפילו גבוה יותר. כדי לעשות את fetchmail
טוב כפי שראיתי עשיו שהוא יכול להיות, הייתי צריך לכתוב אותו לא רק לצרכיי, אלא
גם לכלול ולתמוך ביכולות הדרושות לאחרים אבל מחוץ לתחום שלי. ולעשות זאת כשאני
שומר על התוכנית פשוטה ועמידה.
היכולת הראשונה והכי חשובה במידה מכרעת שכתבתי אחרי שהבנתי זאת הייתה תמיכה ב-multidrop
- היכולת לשלוף דואר מתיבות דואר שצברו את כל הדואר עבור קבוצה של משתמשים,
ואז להעביר כל הודעת דואר לאנשים שהיא יועדה אליהם.
החלטתי להוסיף את התמיכה ב-multidrop חלקית משום שכמה משתמשים ביקשו אותה נמרצות,
אבל בעיקר משום שחשבתי שזה ינער באגים מתוך קוד ה-single-drop בכך שיכריח אותי
לטפל במיעון בכלליות מלאה. וכך זה באמת היה. לדאוג לכך שניתוח הכתובות על-פי
RFC
822 יעבוד כמו שצריך לקח לי זמן רב בצורה ניכרת, לא מכיוון שכל חלק יחיד
שלו הוא קשה אלא משום שהוא נזקק לערמה של פרטים קפריזאיים ותלויים אחד בשני.
אבל מיעון multidrop התברר גם-כן כהחלטת תכנון מצוינת. הנה הסיבה שאני יודע זאת:
14. כל כלי צריך להיות שימושי בדרך לא צפויה, אבל כלי טוב באמת נותן
עצמו לשימושים שלא צפית אותם מעולם.
השימוש הבלתי-צפוי ל-fetchmail במצב multidrop הוא לנהל רשימות תפוצה כאשר הרשימה
נשמרת, והרחבת הכינויים נעשית, בצד ה
לקוח של חיבור האינטרנט. המשמעות
של זה היא שמישהו שמנהל מחשב פרטי דרך חשבון עם ספק אינטרנט יכול לנהל רשימת
תפוצה ללא גישה מתמדת לקבצי הכינויים של הספק.
עוד שינוי חשוב שדרשו בודקי-הבטא שלי היה תמיכה בפעולה מבוססת על MIME (Multipurpose
Internet Mail Extensions) של 8 סיביות. זה היה די קל לעשות, מפני שנזהרתי לשמור
על הקוד נקי מבחינת 8 סיביות (כלומר, לא לרתום את הסיבית השמינית, שהיא לא בשימוש
בסט תווי ה-ASCII, לשרות כדי להעביר מידע בתוך התוכנית). לא מפני שצפיתי את
הדרישה ליכולת זאת, אלא דווקא מתוך ציות לחוק נוסף:
15. בכתיבת תוכנת ניתוב מכל סוג, השתדל להפריע לזרם המידע מעט ככל
האפשר, ולעולם אל תזרוק אינפורמציה אלא אם כן הנמען מכריח אותך לעשות זאת!
אילו לא צייתתי לחוק זה, תמיכה ב-MIME של 8 סיביות הייתה קשה ומלאת שגיאות.
כפי שזה היה, כל שהייתי צריך לעשות הוא לקרוא את סטנדרד ה-MIME (
RFC
1652( ולהוסיף חלק קטן של מה בכך של לוגיקת יצירת-הכותר.
כמה משתמשים אירופאים הטרידו אותי עד לכך שהוספתי אפשרות להגביל את מספר ההודעות
שמובאות בהרצה של התוכנית (כדי שהם יוכלו לשלוט על העלות שדורשות מהם רשתות
הטלפון היקרות שלהם). נמנעתי מכך זמן רב, ואני עדיין לא לגמרי מרוצה מכך. אבל
אם אתה כותב בשביל העולם, עליך להאזין ללקוחות שלך - זה לא משתנה רק בגלל שהם
לא משלמים לך כסף.
מספר לקחים נוספים מ-Fetchmail
לפני שנחזור לענייני הנדסת-תוכנה כללית, ישנם מספר נוסף של לקחים פרטיים מהנסיון
שלי עם fetchmail שאפשר להתעמק בהם. קוראים ללא רקע טכני יכולים בבטחה לדלג על
חלק זה.
תחביר קובץ ה-rc (שליטה) כולל אפשרות לשים מילות-מפתח של "רעש" שהמפענח מתעלם
מהן לחלוטין. התחביר דמוי-האנגלית שהן מאפשרות הוא במידה ניכרת יותר קריא
מזוגות המפתח-ערך המסורתיות התמציתיות שמקבלים כאשר מסירים את כולן.
הן התחילו כניסוי שנעשה מאוחר בלילה כאשר שמתי לב עד כמה הצהרות קובץ ה-rc התחילו
לדמות למיני-שפה החלטתית. (זאת הסיבה הסיבה מדוע שיניתי את מילת-המפתח המקורית
של popclient - "server" ל- "poll").
נדמה היה לי שהנסיון לעשות את אותה מיני-שפה החלטתית דומה יותר לאנגלית, עשוי
לעשות אותה קלה יותר לשימוש. כעת, על אף שאני חסיד משוכנע של אסכולת התכנון
של "הפוך זאת לשפה" כפי שהיא מודגמת על ידי Emacs ו-HTML ומנועי בסיס-נתונים
רבים, אינני בדרך-כלל אוהד תחבירים "דמויי-אנגלית".
באופן מסורתי מתכנתים נטו להעדיף תחבירי שליטה מאוד מדויקים ותמציתיים וללא
כל ייתור. זוהי מורשת תרבותית מהזמן שבו משאבי מחשב היו יקרים, עד ששלבי הפענוח
היו צריכים להיות זולים ופשוטים ככל האפשר. אנגלית עם ייתור של כ50%-, נראתה
כמודל מאוד לא הולם אז.
זו אינה הסיבה שלי לכך שאני בדרך-כלל נמנע מתחבירים דמויי-אנגלית; אני מזכיר
זאת כאן רק כדי להרוס אותה. עם מהירות וליבות זולות, תמציתיות אינה צריכה להיות
מטרה בפני עצמה. בימים אלה, זה יותר חשוב לשפה להיות נוחה לאנשים מאשר זולה
למחשב.
נשארו עדיין, למרות זאת, סיבות טובות להיזהר. אחת היא עלות הסיבוכיות של שלב
הפענוח - לא כדאי להעלות אותו למצב שבו הוא מקור משמעותי של באגים ובלבול למשתמש
בפני עצמו. סיבה נוספת היא שנסיון להפוך תחביר של שפה דומה לאנגלית לעיתים קרובות
דורש שה"אנגלית" שהוא ידבר תעוות באופן רציני, עד כדי כך הרבה שהדמיון השיטחי
לשפה טבעית הוא מבלבל כפי שתחביר מסורתי היה יכול להיות. (ניתן לראות תופעה
לא רצויה זו בהרבה משפות "דור רביעי" (כפי שהן נקראות) ושפות מסחריות לביצוע
שאילתות על בסיסי נתונים.
נראה שתחביר השליטה של fetchmail נמנע מבעיות אלה משום שתחום השפה הוא מוגבל
מאוד. הוא אינו קרוב לשפה לשימוש-כללי; הדברים שהוא אומר הם פשוט לא מאוד מסובכים,
כך שיש פוטנציאל קטן לבלבול במעבר מחשבתי בין חלק מזערי של אנגלית, ושפת השליטה
עצמה. לדעתי, יש כאן לקח רחב יותר:
16. כאשר השפה שלך אינה קרובה להיות שלמת-טיורינג, סוכר תחבירי
יכול לעזור.
לקח נוסף הוא בנוגע לבטיחות על-ידי ערטילאיות ("security by obscurity"). מספר
משתמשים של fetchmail ביקשו ממני לשנות את התוכנה כדי לשמור את הסיסמאות מוצפנות
בקובץ ה-rc, כדי שמרגלים לא יוכל לראות אותן באופן ישיר.
לא עשיתי זאת, בגלל שזה לא ממש מוסיף הגנה. כל מי שקיבל הרשאות לקרוא את קובץ
ה-rc שלך יוכל להריץ את fetchmail בתורך בכל מקרה - ואם אם מעוניינים בסיסמה
שלך, הם יוכלו להוציא את המפענח מתוך הקוד של fetchmail עצמו כדי להשיג אותו.
כל מה שהצפנת סיסמאות ב-.fetchmailrc הייתה עושה היא לתת הרגשה מוטעית של ביטחון
לאנשים שלא חושבים מאוד חזק. הכלל הבסיסי כאן הוא:
17. מערכת אבטחה בטוחה רק כמו הסוד שלה. הזהר מסודות מדומים.