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

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

לא חכם מספיק בשביל הקורס הזה

22/11/2023

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

  • וואו יש פה המון דברים חדשים שאני צריך ללמוד.

  • אני רואה שאצטרך הרבה יותר זמן ממה שתכננתי בשביל לסיים את הקורס הזה.

  • אולי זה עדיין מוקדם מדי בשבילי להיכנס לחומר הזה.

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

בוא ננסה

21/11/2023

המשפט שאני הכי אוהב להגיד, והכי לא אוהב לשמוע.

לא היית רוצה לשמוע "בוא ננסה" מהרופאה לפני שאתה נכנס לניתוח.

לא היית רוצה לשמוע "אולי זה יעבוד" מהאינסטלטור כשיש סתימה בצנרת.

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

בוא ננסה. אולי זה יעבוד.

אבל זה עובד

20/11/2023

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

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

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

צעדים ראשונים עם jotai

19/11/2023

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

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

המשך קריאה

יציאה מלולאה בסקאלה

18/11/2023

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

while True:
    line = input()
    print(line)
    if line == "stop":
        break

בואו ננסה לתרגם אותה לסקאלה.

המשך קריאה

היום שאחרי

17/11/2023

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

איפה אהיה בעוד חמש שנים?

על איזה פרויקטים אעבוד?

האם זה עדיין יעניין אותי?

הבעיה עם לא לחשוב על היום שאחרי היא ש"היום שאחרי" יגיע בין אם נרצה או לא.

ויותר קל לבנות את החיים הטובים ביום שאחרי כשמתחילים לתכנן מהיום.

שימו לב: הגדרת משתני סביבה בתחילת פקודה

16/11/2023

רוב ה Shell-ים תומכים בכתיב של הגדרת משתני סביבה לפני פקודה ובגלל זה אפשר לכתוב:

FOO=10 bash -c 'echo $FOO'

ולקבל על המסך את המספר 10.

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

RUN apt-get update && apt-get install cowsay

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

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install cowsay

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

FOO=10 bash -c 'echo $FOO' && bash -c 'echo $FOO'

הפעם השורה תדפיס 10 רק פעם אחת, למרות שפקודת ההדפסה מופיעה פעמיים.

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

RUN DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install cowsay

אפשרות קצת יותר נוחה היא להוסיף אותו בשורת ENV לפני הרצת הפקודה:

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install cowsay

הדף הכי חשוב בתיעוד (שברוב המקרים בכלל לא כתוב)

15/11/2023

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

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

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

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

הקושי לזהות בשר מקולקל

14/11/2023

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

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

"אני לא רוצה שזה יהיה מקולקל" לא יהפוך אותו לטרי.

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

13/11/2023

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

אחד הטריקים שלמדתי לאחרונה הוא קיצור דרך לפונקציה שמחזירה פונקציה. מה שב JavaScript נראה ככה:

const add = x => y => x + y;

(שגם בשעתו נראה לי כמו קסם אבל היום כבר הגיוני לגמרי).

ובפייתון אנחנו כותבים:

def add(x):
    return lambda y: x + y

מקבל בסקאלה קיצור דרך כבר ברמת החתימה של הפונקציה:

def add(x: Int)(y: Int): Int = x + y

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

def add2(x: Int): (y: Int) => Int = { y =>
  x + y
}

אבל זה פשוט פחות יפה.