הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

נתחיל בדרך שמובנית בשפה

17/01/2024

אחת הטעויות הנפוצות בלימוד טכנולוגיה מתחילה כשאנחנו מסתכלים על Tech Stack במקום על שפה, ומנסים ללמוד סטאק שלם במכה אחת. זה יהיה הניסיון ללמוד Node.js יחד עם אקספרס, או רובי יחד עם ריילס, אבל גם ריאקט יחד עם רידאקס ו next ו styled components ו TypeScript.

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

  1. אנחנו מפתחים תלות בפריימוורק כך שיהיה לנו קשה להחליף חלקים ממנה.

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

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

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

האם Exceptions צריכים להיות חלק מהממשק?

16/01/2024

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

בצד השני של המפה יש לנו את פייתון שמציינת ב PEP484:

No syntax for listing explicitly raised exceptions is proposed. Currently the only known use case for this feature is documentational, in which case the recommendation is to put this information in a docstring.

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

הבעיה הגדולה שלנו היא שמצד אחד אנחנו לא רוצים להכריח אף אחד לטפל בשגיאות (כי לכל פרויקט יש דרישות שונות), אבל מצד שני זה מרגיש לא נכון לטעון שיש לנו Type Safety כשבעצם קוד יכול "לקפוץ" למקומות אחרים בגלל פקודה בפונקציה פנימית.

מה דעתכם? האם Exceptions צריכים להיות חלק מהממשק? מעדיפים קוד שמחזיר שגיאה או שזורק Exception, ובאיזה מצבים?

מה אנחנו מחפשים בשפת תכנות

15/01/2024

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

  1. קשה לגייס אנשים ועלות מפתחים מאוד גבוהה.

  2. אקוסיסטם מפוצל ולא מתוחזק.

  3. אין עבודה.

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

למרות המעמד הגבוה של Python ו JavaScript בימים אלה, כדאי לזכור את הלקח של סקאלה, רובי, פרל ושפות רבות נוספות. העולם ישתנה ושפות חדשות יגיעו. ככל שאפשר שווה להתרגל ללימוד שפות תכנות חדשות אפילו בתור תחביב, כדי שכשיגיע היום והשפה שלנו תתחיל לאבד גובה נוכל להתקדם ולא להרגיש תקועים.

טעות באבסטרקציה

13/01/2024

כשאני מלמד Generators בפייתון אני אוהב להתחיל עם הפונקציה הזאת שמחשבת מספר בסידרת פיבונאצ'י:

def fib(n: int) -> int:
    a, b = 1, 1
    for i in range(n):
        a, b = b, a + b
    return a

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

print(sum(fib(n) for n in range(100)))

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

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

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

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

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

אתגרים או תירוצים

12/01/2024

שנה חדשה, פרויקטים חדשים, חלומות חדשים, אבל כשהחלומות האלה מתחילים להיתקל בקשיים יש לנו שתי אסטרטגיות תגובה-

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

  2. אפשר להתייחס לקושי החדש בתור תירוץ, ולהסביר לעצמי ולעולם למה אי אפשר להגשים את החלום.

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

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

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

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

טכנולוגיה משעממת או חדשה?

11/01/2024

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

  1. חיבור טוב לכל מערכת צד שלישי שאפשר לדמיין.

  2. תיעוד טוב ברשת ופיתרונות קיימים לכל בעיה.

  3. יכולת שיחה עם Chat GPT בלי להפיל אותו להזיות.

  4. קל לגייס אנשים (כן עם כל ההייפ, עדיין קל יותר לגייס מתכנתי Java מאשר מתכנתי Rust).

  5. לא משנה איזה בעיה יש לכם, מישהו אחר כבר שבר את הראש וכתב תשובה באינטרנט. הרבה פעמים הפיתרון אפילו מובנה כבר בשפה.

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

  1. אפשר לפתח לבד את כל הכלים ולקבל רוח גבית חזקה מהאינטרנט גם לפרויקטים קטנים.

  2. פוסטים הופכים ויראליים הרבה יותר מהר (כי מי בכלל הולך לשתף פוסט על Java היום)

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

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

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

פרדוקס השידרוגים

09/01/2024

הסתכלתי היום ברשימת החידושים של רובי 3.3, וכמו בהרבה מקרים של גירסאות חדשות של שפות תכנות, ולמרות שממש חיפשתי, לא היה שם אפילו פיצ'ר אחד שבשבילו היה שווה לשדרג.

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

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

ומכאן צריך לבחור דרך פעולה-

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

  2. או ששידרוג זה משהו שעושים כל X זמן בשביל לאפשר תמיד להשתמש בפיצ'רים שראיתי בתיעוד וב Best Practices הכי מודרניים, כשיתחשק לעשות את זה.

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

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

אז כן אני שמח היום שאני יכול לכתוב ברובי קוד כזה:

3.1.1 :008 > x = 10
 => 10
3.1.1 :009 > y = 20
 => 20
3.1.1 :010 > data = {x:, y:}
 => {:x=>10, :y=>20}

אבל כשיצאה רובי 2.7 והייתי צריך להתרגל לכתיב הזה זה גם נראה לי מוזר.

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